From 550bd2ddbe3647436a3486254c5650a4c76db594 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Fri, 29 Sep 2023 11:27:39 +1300 Subject: [PATCH] Allow ::string and ::number in list of nonlinear nodes (#35) --- README.md | 179 +---- examples/nlp.mof.json | 55 +- python/mof.py | 7 + schemas/mof.1.7.schema.json | 1281 +++++++++++++++++++++++++++++++++++ schemas/mof.1.schema.json | 35 +- 5 files changed, 1354 insertions(+), 203 deletions(-) create mode 100644 schemas/mof.1.7.schema.json diff --git a/README.md b/README.md index ea79510..37b78ad 100644 --- a/README.md +++ b/README.md @@ -290,11 +290,11 @@ Leaf nodes in the expression graph are data: they can either reference optimization variables, or be real or complex valued numeric constants. They are described as follows. -| Head | Description | Example | +| Type | Description | Example | | ---- | ----------- | ------- | -| `"real"` | A real-valued numeric constant | {"type": "real", "value": 1.0} | -| `"complex"` | A complex-valued numeric constant | {"type": "complex", "real": 1.0, "imag": 2.0} | -| `"variable"` | A reference to an optimization variable | {"type": "variable", "name": "x"} | +| `number` | A real-valued numeric constant | 1.0 | +| `string` | A reference to an optimization variable | "x" | +| `{"type": "complex"}` | A complex-valued numeric constant | {"type": "complex", "real": 1.0, "imag": 2.0} | Nodes in the flattened list `"node_list"` can be referenced by an object with the `"type"` field `"node"` and a field `"index"` that is the one-based index of @@ -306,17 +306,15 @@ the node in `"node_list"`. #### Operators -All nonlinear operators in MathOptFormat are described by a JSON object with two fields: - - - `"type"` - - A string that corresponds to the operator. +All nonlinear operators in MathOptFormat are described by a JSON object with two +fields: - - `"args"` + - `"type"`: A string that corresponds to the operator. + - `"args"`: An ordered list of nodes that are passed as arguments to the + operator. - An ordered list of nodes that are passed as arguments to the operator. - -The number of elements in `"args"` depends on the arity of the operator. MathOptFormat distinguishes between three arities: +The number of elements in `"args"` depends on the arity of the operator. +MathOptFormat distinguishes between three arities: - Unary operators take one argument - Binary operators take two arguments @@ -324,130 +322,25 @@ The number of elements in `"args"` depends on the arity of the operator. MathOpt To give some examples, the unary function `log(x)` is encoded as: ```json -{ - "type": "log", - "args": [ - {"type": "variable", "name": "x"} - ] -} +{"type": "log", "args": ["x"]} ``` The binary function `x^2` (i.e., `^(x, 2)`) is encoded as: ```json -{ - "type": "^", - "args": [ - {"type": "variable", "name": "x"}, - {"type": "real", "value": 2} - ] -} +{"type": "^", "args": ["x", 2]} ``` The n-ary function `x + y + 1` (i.e., `+(x, y, 1)`) is encoded as: ```json -{ - "type": "+", - "args": [ - {"type": "variable", "name": "x"}, - {"type": "variable", "name": "y"}, - {"type": "real", "value": 1} - ] -} +{"type": "+", "args": ["x", "y", 1.0]} ``` Here is a complete list of the nonlinear operators supported by MathOptFormat and their corresponding arity. -| Name | Arity | -| ---- | ----- | -| `"+"` | Unary | -| `"-"` | Unary | -| `"abs"` | Unary | -| `"sqrt"` | Unary | -| `"cbrt"` | Unary | -| `"abs2"` | Unary | -| `"inv"` | Unary | -| `"log"` | Unary | -| `"log10"` | Unary | -| `"log2"` | Unary | -| `"log1p"` | Unary | -| `"exp"` | Unary | -| `"exp2"` | Unary | -| `"expm1"` | Unary | -| `"sin"` | Unary | -| `"cos"` | Unary | -| `"tan"` | Unary | -| `"sec"` | Unary | -| `"csc"` | Unary | -| `"cot"` | Unary | -| `"sind"` | Unary | -| `"cosd"` | Unary | -| `"tand"` | Unary | -| `"secd"` | Unary | -| `"cscd"` | Unary | -| `"cotd"` | Unary | -| `"asin"` | Unary | -| `"acos"` | Unary | -| `"atan"` | Unary | -| `"asec"` | Unary | -| `"acsc"` | Unary | -| `"acot"` | Unary | -| `"asind"` | Unary | -| `"acosd"` | Unary | -| `"atand"` | Unary | -| `"asecd"` | Unary | -| `"acscd"` | Unary | -| `"acotd"` | Unary | -| `"sinh"` | Unary | -| `"cosh"` | Unary | -| `"tanh"` | Unary | -| `"sech"` | Unary | -| `"csch"` | Unary | -| `"coth"` | Unary | -| `"asinh"` | Unary | -| `"acosh"` | Unary | -| `"atanh"` | Unary | -| `"asech"` | Unary | -| `"acsch"` | Unary | -| `"acoth"` | Unary | -| `"deg2rad"` | Unary | -| `"rad2deg"` | Unary | -| `"erf"` | Unary | -| `"erfinv"` | Unary | -| `"erfc"` | Unary | -| `"erfcinv"` | Unary | -| `"erfi"` | Unary | -| `"gamma"` | Unary | -| `"lgamma"` | Unary | -| `"digamma"` | Unary | -| `"invdigamma"` | Unary | -| `"trigamma"` | Unary | -| `"airyai"` | Unary | -| `"airybi"` | Unary | -| `"airyaiprime"` | Unary | -| `"airybiprime"` | Unary | -| `"besselj0"` | Unary | -| `"besselj1"` | Unary | -| `"bessely0"` | Unary | -| `"bessely1"` | Unary | -| `"erfcx"` | Unary | -| `"dawson"` | Unary | -| `"floor"` | Unary | -| `"ceil"` | Unary | -| `"/"` | Binary | -| `"^"` | Binary | -| `"atan"` | Binary | -| `"&&"` | Binary | -| `"||"` | Binary | -| `"<="` | Binary | -| `"<"` | Binary | -| `">="` | Binary | -| `">"` | Binary | -| `"=="` | Binary | -| `"+"` | N-ary | -| `"-"` | N-ary | -| `"*"` | N-ary | -| `"ifelse"` | N-ary | -| `"min"` | N-ary | -| `"max"` | N-ary | +| Arity | Operators | +| ----- | --------- | +| Unary | `"abs"`, `"sqrt"`, `"cbrt"`, `"abs2"`, `"inv"`, `"log"`, `"log10"`, `"log2"`, `"log1p"`, `"exp"`, `"exp2"`, `"expm1"`, `"sin"`, `"cos"`, `"tan"`, `"sec"`, `"csc"`, `"cot"`, `"sind"`, `"cosd"`, `"tand"`, `"secd"`, `"cscd"`, `"cotd"`, `"asin"`, `"acos"`, `"atan"`, `"asec"`, `"acsc"`, `"acot"`, `"asind"`, `"acosd"`, `"atand"`, `"asecd"`, `"acscd"`, `"acotd"`, `"sinh"`, `"cosh"`, `"tanh"`, `"sech"`, `"csch"`, `"coth"`, `"asinh"`, `"acosh"`, `"atanh"`, `"asech"`, `"acsch"`, `"acoth"`, `"deg2rad"`, `"rad2deg"`, `"erf"`, `"erfinv"`, `"erfc"`, `"erfcinv"`, `"erfi"`, `"gamma"`, `"lgamma"`, `"digamma"`, `"invdigamma"`, `"trigamma"`, `"airyai"`, `"airybi"`, `"airyaiprime"`, `"airybiprime"`, `"besselj0"`, `"besselj1"`, `"bessely0"`, `"bessely1"`, `"erfcx"`, `"dawson"`, `"floor"`, `"ceil"` | +| Binary | `"/"`, `"^"`, `"atan"`, `"&&"`, `"\|\|"`, `"<="`, `"<"`, `">="`, `">"`, `"=="` | +| N-ary | `"+"`, `"-"`, `"*"`, `"ifelse"`, `"min"`, `"max"` | #### Example @@ -462,31 +355,15 @@ In MathOptFormat, this expression graph can be encoded as follows: "type": "ScalarNonlinearFunction", "root": { "type": "+", - "args": [ - {"type": "node", "index": 1}, - {"type": "node", "index": 3}, - {"type": "variable", "name": "y"} - ] + "args": [{"type": "node", "index": 1}, {"type": "node", "index": 3}, "y"] }, - "node_list": [ - { - "type": "*", - "args": [ - {"type": "complex", "real": 1, "imag": 3}, - {"type": "variable", "name": "x"} - ] - }, { - "type": "sin", - "args": [ - {"type": "variable", "name": "x"} - ] - }, { - "type": "^", - "args": [ - {"type": "node", "index": 2}, - {"type": "real", "value": 2} - ] - } - ] + "node_list": [{ + "type": "*", + "args": [{"type": "complex", "real": 1, "imag": 3}, "x"] + }, { + "type": "sin", "args": ["x"] + }, { + "type": "^", "args": [{"type": "node", "index": 2}, 2] + }] } ``` diff --git a/examples/nlp.mof.json b/examples/nlp.mof.json index 613854c..048716e 100644 --- a/examples/nlp.mof.json +++ b/examples/nlp.mof.json @@ -1,58 +1,31 @@ { "description": "The problem: min{2x + sin(x)^2 + y}.", - "version": { - "major": 1, - "minor": 1 - }, - "variables": [{ - "name": "x" - }, { - "name": "y" - }], + "version": {"major": 1, "minor": 7}, + "variables": [{"name": "x"}, {"name": "y"}], "objective": { "sense": "min", "function": { "type": "ScalarNonlinearFunction", - "root": { - "type": "node", - "index": 4 - }, + "root": {"type": "node", "index": 4}, "node_list": [{ "type": "*", - "args": [{ - "type": "real", - "value": 2 - }, { - "type": "variable", - "name": "x" - }] + "args": [ + {"type": "real", "value": 2}, + {"type": "variable", "name": "x"} + ] }, { "type": "sin", - "args": [{ - "type": "variable", - "name": "x" - }] + "args": ["x"] }, { "type": "^", - "args": [{ - "type": "node", - "index": 2 - }, { - "type": "real", - "value": 2 - }] + "args": [{"type": "node", "index": 2}, 2.0] }, { "type": "+", - "args": [{ - "type": "node", - "index": 1 - }, { - "type": "node", - "index": 3 - }, { - "type": "variable", - "name": "y" - }] + "args": [ + {"type": "node", "index": 1}, + {"type": "node", "index": 3}, + "y" + ] }] } }, diff --git a/python/mof.py b/python/mof.py index 53f14bc..7edd8ca 100644 --- a/python/mof.py +++ b/python/mof.py @@ -28,6 +28,13 @@ def summarize_schema(): return summary def oneOf_to_object(item): + if "properties" not in item: + print(item) + return [{ + "name": None, + "description": item["description"], + "example": item["examples"][0], + }] head = item["properties"]["type"] ret = [] if "const" in head: diff --git a/schemas/mof.1.7.schema.json b/schemas/mof.1.7.schema.json new file mode 100644 index 0000000..ef3b274 --- /dev/null +++ b/schemas/mof.1.7.schema.json @@ -0,0 +1,1281 @@ +{ + "$schema": "https://json-schema.org/schema#", + "$id": "https://jump.dev/MathOptFormat/schemas/mof.1.7.schema.json", + "title": "The schema for MathOptFormat", + "type": "object", + "required": ["version", "variables", "objective", "constraints"], + "properties": { + "version": { + "description": "The version of MathOptFormat that this schema validates against.", + "type": "object", + "required": ["minor", "major"], + "properties": { + "minor": { + "enum": [0, 1, 2, 3, 4, 5, 6, 7] + }, + "major": { + "const": 1 + } + } + }, + "name": { + "description": "The name of the model.", + "type": "string" + }, + "author": { + "description": "The author of the model for citation purposes.", + "type": "string" + }, + "description": { + "description": "A human-readable description of the model.", + "type": "string" + }, + "variables": { + "description": "An array of variables in the model. Each must have a unique name.", + "type": "array", + "items": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string" + }, + "primal_start": { + "description": "An initial value for the variable's primal solution that the optimizer may use to warm-start the solution process.", + "type": "number" + } + } + }, + "uniqueItems": true + }, + "objective": { + "description": "The objective of the model.", + "type": "object", + "required": ["sense"], + "oneOf": [{ + "properties": { + "sense": { + "enum": ["min", "max"] + }, + "function": { + "oneOf": [{ + "$ref": "#/definitions/scalar_functions" + }, { + "$ref": "#/definitions/vector_functions" + }] + } + } + }, { + "properties": { + "sense": { + "const": "feasibility" + } + } + }] + }, + "constraints": { + "description": "An array of constraints in the model. Scalar-valued functions can only be paired with scalar-sets, and the same applies for vector-valued functions and sets.", + "type": "array", + "items": { + "type": "object", + "required": ["function", "set"], + "properties": { + "name": { + "type": "string" + } + }, + "oneOf": [{ + "description": "A scalar-valued constraint.", + "properties": { + "function": { + "$ref": "#/definitions/scalar_functions" + }, + "set": { + "$ref": "#/definitions/scalar_sets" + }, + "primal_start": { + "description": "An initial scalar value for the constraint's primal solution that the optimizer may use to warm-start the solution process.", + "type": "number" + }, + "dual_start": { + "description": "An initial scalar value for the constraint's dual solution that the optimizer may use to warm-start the solution process.", + "type": "number" + } + } + }, { + "description": "A vector-valued constraint.", + "properties": { + "function": { + "$ref": "#/definitions/vector_functions" + }, + "set": { + "$ref": "#/definitions/vector_sets" + }, + "primal_start": { + "description": "An initial vector for the constraint's primal solution that the optimizer may use to warm-start the solution process.", + "type": "array", + "items": { + "type": "number" + } + }, + "dual_start": { + "description": "An initial vector for the constraint's dual solution that the optimizer may use to warm-start the solution process.", + "type": "array", + "items": { + "type": "number" + } + } + } + }] + }, + "uniqueItems": true + } + }, + "definitions": { + "ScalarAffineTerm": { + "description": "A helper object that represents `coefficent * variable`.", + "type": "object", + "required": ["coefficient", "variable"], + "properties": { + "coefficient": { + "type": "number" + }, + "variable": { + "type": "string" + } + } + }, + "ScalarQuadraticTerm": { + "description": "A helper object that represents `coefficent * variable_1 * variable_2`.", + "type": "object", + "required": ["coefficient", "variable_1", "variable_2"], + "properties": { + "coefficient": { + "type": "number" + }, + "variable_1": { + "type": "string" + }, + "variable_2": { + "type": "string" + } + } + }, + "VectorAffineTerm": { + "description": "A helper object that represents a `ScalarAffineTerm` in row `output_index`.", + "type": "object", + "required": ["output_index", "scalar_term"], + "properties": { + "output_index": { + "type": "integer", + "minimum": 1 + }, + "scalar_term": { + "$ref": "#/definitions/ScalarAffineTerm" + } + } + }, + "VectorQuadraticTerm": { + "description": "A helper object that represents a `ScalarQuadraticTerm` in row `output_index`.", + "type": "object", + "required": ["output_index", "scalar_term"], + "properties": { + "output_index": { + "type": "integer", + "minimum": 1 + }, + "scalar_term": { + "$ref": "#/definitions/ScalarQuadraticTerm" + } + } + }, + "NonlinearTerm": { + "description": "A node in an expresion graph representing a nonlinear function.", + "oneOf": [{ + "description": "Unary operators", + "type": "object", + "required": ["type", "args"], + "properties": { + "type": { + "enum": [ + "abs", + "sqrt", + "cbrt", + "abs2", + "inv", + "log", + "log10", + "log2", + "log1p", + "exp", + "exp2", + "expm1", + "sin", + "cos", + "tan", + "sec", + "csc", + "cot", + "sind", + "cosd", + "tand", + "secd", + "cscd", + "cotd", + "asin", + "acos", + "atan", + "asec", + "acsc", + "acot", + "asind", + "acosd", + "atand", + "asecd", + "acscd", + "acotd", + "sinh", + "cosh", + "tanh", + "sech", + "csch", + "coth", + "asinh", + "acosh", + "atanh", + "asech", + "acsch", + "acoth", + "deg2rad", + "rad2deg", + "erf", + "erfinv", + "erfc", + "erfcinv", + "erfi", + "gamma", + "lgamma", + "digamma", + "invdigamma", + "trigamma", + "airyai", + "airybi", + "airyaiprime", + "airybiprime", + "besselj0", + "besselj1", + "bessely0", + "bessely1", + "erfcx", + "dawson", + "floor", + "ceil" + ] + }, + "args": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + }, + "minItems": 1, + "maxItems": 1 + } + } + }, { + "description": "Binary operators", + "type": "object", + "required": ["type", "args"], + "properties": { + "type": { + "enum": [ + "/", + "^", + "atan", + "&&", + "||", + "<=", + "<", + ">=", + ">", + "==" + ] + }, + "args": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + }, + "minItems": 2, + "maxItems": 2 + } + } + }, { + "description": "N-ary operators", + "type": "object", + "required": ["type", "args"], + "properties": { + "type": { + "enum": ["+", "-", "*", "ifelse", "min", "max"] + }, + "args": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + }, + "minItems": 1 + } + } + }, { + "description": "A real-valued numeric constant", + "examples": ["{\"type\": \"real\", \"value\": 1.0}"], + "type": "object", + "required": ["type", "value"], + "properties": { + "type": { + "const": "real" + }, + "value": { + "type": "number" + } + } + }, { + "description": "A complex-valued numeric constant", + "examples": ["{\"type\": \"complex\", \"real\": 1.0, \"imag\": 2.0}"], + "type": "object", + "required": ["type", "real", "imag"], + "properties": { + "type": { + "const": "complex" + }, + "real": { + "type": "number" + }, + "imag": { + "type": "number" + } + } + }, { + "description": "A reference to an optimization variable", + "examples": ["{\"type\": \"variable\", \"name\": \"x\"}"], + "type": "object", + "required": ["type", "name"], + "properties": { + "type": { + "const": "variable" + }, + "name": { + "type": "string" + } + } + }, { + "description": "A pointer to a (1-indexed) element in the `node_list` field in a nonlinear function", + "examples": ["{\"type\": \"node\", \"index\": 2}"], + "type": "object", + "required": ["type", "index"], + "properties": { + "type": { + "const": "node" + }, + "index": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "A reference to an optimization variable", + "examples": ["\"x\""], + "type": "string" + }, { + "description": "A real-valued numeric constant", + "examples": [1.0], + "type": "number" + }] + }, + "scalar_functions": { + "description": "A schema for the scalar-valued functions defined by MathOptFormat.See http://www.juliaopt.org/MathOptInterface.jl/v0.8/apireference/#Functions-and-function-modifications-1 for a list of the functions and their meanings.", + "type": "object", + "required": ["type"], + "oneOf": [{ + "description": "The scalar variable `x`.", + "examples": ["{\"type\": \"Variable\", \"name\": \"x\"}"], + "required": ["name"], + "properties": { + "type": { + "const": "Variable" + }, + "name": { + "type": "string" + } + } + }, { + "description": "The function `a'x + b`, where `a` is a sparse vector specified by a list of `ScalarAffineTerm`s in `terms` and `b` is the scalar in `constant`. Duplicate variables in `terms` are accepted, and the corresponding coefficients are summed together.", + "examples": ["{\"type\": \"ScalarAffineFunction\", \"constant\": 1.0, \"terms\": [{\"coefficient\": 2.5, \"variable\": \"x\"}]}"], + "required": ["constant", "terms"], + "properties": { + "type": { + "const": "ScalarAffineFunction" + }, + "constant": { + "type": "number" + }, + "terms": { + "type": "array", + "items": { + "$ref": "#/definitions/ScalarAffineTerm" + } + } + } + }, { + "description": "The function `0.5x'Qx + a'x + b`, where `a` is a sparse vector of `ScalarAffineTerm`s in `affine_terms`, `b` is the scalar `constant`, and `Q` is a symmetric matrix specified by a list of `ScalarQuadraticTerm`s in `quadratic_terms`. Duplicate indices in `affine_terms` and `quadratic` are accepted, and the corresponding coefficients are summed together. Mirrored indices in `quadratic_terms` (i.e., `(i,j)` and `(j, i)`) are considered duplicates; only one need to be specified.", + "examples": ["{\"type\": \"ScalarQuadraticFunction\", \"constant\": 1.0, \"affine_terms\": [{\"coefficient\": 2.5, \"variable\": \"x\"}], \"quadratic_terms\": [{\"coefficient\": 2.0, \"variable_1\": \"x\", \"variable_2\": \"y\"}]}"], + "required": ["constant", "affine_terms", "quadratic_terms"], + "properties": { + "type": { + "const": "ScalarQuadraticFunction" + }, + "constant": { + "type": "number" + }, + "affine_terms": { + "type": "array", + "items": { + "$ref": "#/definitions/ScalarAffineTerm" + } + }, + "quadratic_terms": { + "type": "array", + "items": { + "$ref": "#/definitions/ScalarQuadraticTerm" + } + } + } + }, { + "description": "An expression graph representing a scalar nonlinear function.", + "required": ["root", "node_list"], + "properties": { + "type": { + "const": "ScalarNonlinearFunction" + }, + "root": { + "$ref": "#/definitions/NonlinearTerm" + }, + "node_list": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + } + } + } + }] + }, + "vector_functions": { + "description": "A schema for the vector-valued functions defined by MathOptFormat.See http://www.juliaopt.org/MathOptInterface.jl/v0.8/apireference/#Functions-and-function-modifications-1 for a list of the functions and their meanings.", + "type": "object", + "required": ["type"], + "oneOf": [{ + "description": "An ordered list of variables.", + "examples": ["{\"type\": \"VectorOfVariables\", \"variables\": [\"x\", \"y\"]}"], + "required": ["variables"], + "properties": { + "type": { + "const": "VectorOfVariables" + }, + "variables": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, { + "description": "The function `Ax + b`, where `A` is a sparse matrix specified by a list of `VectorAffineTerm`s in `terms` and `b` is a dense vector specified by `constants`.", + "examples": ["{\"type\": \"VectorAffineFunction\", \"constants\": [1.0], \"terms\": [{\"output_index\": 1, \"scalar_term\": {\"coefficient\": 2.5, \"variable\": \"x\"}}]}"], + "required": ["constants", "terms"], + "properties": { + "type": { + "const": "VectorAffineFunction" + }, + "constants": { + "type": "array", + "items": { + "type": "number" + } + }, + "terms": { + "type": "array", + "items": { + "$ref": "#/definitions/VectorAffineTerm" + } + } + } + }, { + "description": "The vector-valued quadratic function `q(x) + Ax + b`, where `q(x)` is specified by a list of `VectorQuadraticTerm`s in `quadratic_terms`, `A` is a sparse matrix specified by a list of `VectorAffineTerm`s in `affine_terms` and `b` is a dense vector specified by `constants`.", + "required": ["constants", "affine_terms", "quadratic_terms"], + "properties": { + "type": { + "const": "VectorQuadraticFunction" + }, + "constants": { + "type": "array", + "items": { + "type": "number" + } + }, + "affine_terms": { + "type": "array", + "items": { + "$ref": "#/definitions/VectorAffineTerm" + } + }, + "quadratc_terms": { + "type": "array", + "items": { + "$ref": "#/definitions/VectorQuadraticTerm" + } + } + } + }, { + "description": "The vector-valued nonlinear function `f(x)`, comprised of a vector of `ScalarNonlinearFunction`.", + "required": ["rows", "node_list"], + "properties": { + "type": { + "const": "VectorNonlinearFunction" + }, + "rows": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + } + }, + "node_list": { + "type": "array", + "items": { + "$ref": "#/definitions/NonlinearTerm" + } + } + } + }] + }, + "scalar_sets": { + "description": "A schema for the scalar-valued sets defined by MathOptFormat. See http: //www.juliaopt.org/MathOptInterface.jl/v0.8/apireference/#Sets-1 for a list of the sets and their meanings.", + "type": "object", + "required": ["type"], + "oneOf": [{ + "description": "(-∞, upper]", + "examples": ["{\"type\": \"LessThan\", \"upper\": 2.1}"], + "required": ["upper"], + "properties": { + "type": { + "const": "LessThan" + }, + "upper": { + "type": "number" + } + } + }, { + "description": "[lower, ∞)", + "examples": ["{\"type\": \"GreaterThan\", \"lower\": 2.1}"], + "required": ["lower"], + "properties": { + "type": { + "const": "GreaterThan" + }, + "lower": { + "type": "number" + } + } + }, { + "description": "{value}", + "examples": ["{\"type\": \"EqualTo\", \"value\": 2.1}"], + "required": ["value"], + "properties": { + "type": { + "const": "EqualTo" + }, + "value": { + "type": "number" + } + } + }, { + "description": "[lower, upper]", + "examples": ["{\"type\": \"Interval\", \"lower\": 2.1, \"upper\": 3.4}"], + "required": ["lower", "upper"], + "properties": { + "type": { + "const": "Interval" + }, + "lower": { + "type": "number" + }, + "upper": { + "type": "number" + } + } + }, { + "description": "{0} ∪ {lower, lower + 1, ..., upper}", + "examples": ["{\"type\": \"Semiinteger\", \"lower\": 2, \"upper\": 4}"], + "required": ["lower", "upper"], + "properties": { + "type": { + "const": "Semiinteger" + }, + "lower": { + "type": "number" + }, + "upper": { + "type": "number" + } + } + }, { + "description": "{0} ∪ [lower, upper]", + "examples": ["{\"type\": \"Semicontinuous\", \"lower\": 2.1, \"upper\": 3.4}"], + "required": ["lower", "upper"], + "properties": { + "type": { + "const": "Semicontinuous" + }, + "lower": { + "type": "number" + }, + "upper": { + "type": "number" + } + } + }, { + "description": "{0, 1}", + "examples": ["{\"type\": \"ZeroOne\"}"], + "properties": { + "type": { + "const": "ZeroOne" + } + } + }, { + "description": "ℤ", + "examples": ["{\"type\": \"Integer\"}"], + "properties": { + "type": { + "const": "Integer" + } + } + }, { + "description": "{value}", + "examples": ["{\"type\": \"Parameter\", \"value\": 2.1}"], + "required": ["value"], + "properties": { + "type": { + "const": "Parameter" + }, + "value": { + "type": "number" + } + } + }] + }, + "vector_sets": { + "description": "A schema for the vector-valued sets defined by MathOptFormat. See http: //www.juliaopt.org/MathOptInterface.jl/v0.8/apireference/#Sets-1 for a list of the sets and their meanings.", + "type": "object", + "required": ["type"], + "oneOf": [{ + "description": "[x, y, z] ∈ {R³: y * exp(x / y) ≤ z, y ≥ 0}", + "examples": ["{\"type\": \"ExponentialCone\"}"], + "properties": { + "type": { + "const": "ExponentialCone" + } + } + }, { + "description": "[u, v, w] ∈ {R³: -u * exp(v / u) ≤ exp(1) * w, u < 0}", + "examples": ["{\"type\": \"DualExponentialCone\"}"], + "properties": { + "type": { + "const": "DualExponentialCone" + } + } + }, { + "description": "A special ordered set of type I.", + "examples": ["{\"type\": \"SOS1\", \"weights\": [1, 3, 2]}"], + "required": ["weights"], + "properties": { + "type": { + "const": "SOS1" + }, + "weights": { + "type": "array", + "items": { + "type": "number" + } + } + } + }, { + "description": "A special ordered set of type II.", + "examples": ["{\"type\": \"SOS2\", \"weights\": [1, 3, 2]}"], + "required": ["weights"], + "properties": { + "type": { + "const": "SOS2" + }, + "weights": { + "type": "array", + "items": { + "type": "number" + } + } + } + }, { + "description": "[t, x] ∈ {R^{dimension}: t ≤ (Πxᵢ)^{1 / (dimension-1)}}", + "examples": ["{\"type\": \"GeometricMeanCone\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "GeometricMeanCone" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "[t, x] ∈ {R^{dimension} : t ≥ ||x||₂", + "examples": ["{\"type\": \"SecondOrderCone\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "SecondOrderCone" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "[t, u, x] ∈ {R^{dimension} : 2tu ≥ (||x||₂)²; t, u ≥ 0}", + "examples": ["{\"type\": \"RotatedSecondOrderCone\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "RotatedSecondOrderCone" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "{0}^{dimension}", + "examples": ["{\"type\": \"Zeros\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Zeros" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "R^{dimension}", + "examples": ["{\"type\": \"Reals\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Reals" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "R₋^{dimension}", + "examples": ["{\"type\": \"Nonpositives\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Nonpositives" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "R₊^{dimension}", + "examples": ["{\"type\": \"Nonnegatives\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Nonnegatives" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "{[t, X] ∈ R^{1 + d(d+1)/2} : t ≤ det(X)^{1/d}}, where the matrix `X` is represented in the same symmetric packed format as in the `PositiveSemidefiniteConeTriangle`. The argument `side_dimension` is the side dimension of the matrix `X`, i.e., its number of rows or columns.", + "examples": ["{\"type\": \"RootDetConeTriangle\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "RootDetConeTriangle" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "{[t, X] ∈ R^{1 + d^2} : t ≤ det(X)^{1/d}, X symmetric}, where the matrix `X` is represented in the same symmetric packed format as in the `PositiveSemidefiniteConeSquare`. The argument `side_dimension` is the side dimension of the matrix `X`, i.e., its number of rows or columns.", + "examples": ["{\"type\": \"RootDetConeSquare\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "RootDetConeSquare" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "{[t, u, X] ∈ R^{2 + d(d+1)/2} : t ≤ u log(det(X/u)), u > 0}, where the matrix `X` is represented in the same symmetric packed format as in the `PositiveSemidefiniteConeTriangle`. The argument `side_dimension` is the side dimension of the matrix `X`, i.e., its number of rows or columns.", + "examples": ["{\"type\": \"LogDetConeTriangle\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "LogDetConeTriangle" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "{[t, u, X] ∈ R^{2 + d^2} : t ≤ u log(det(X/u)), X symmetric, u > 0}, where the matrix `X` is represented in the same symmetric packed format as in the `PositiveSemidefiniteConeSquare`. The argument `side_dimension` is the side dimension of the matrix `X`, i.e., its number of rows or columns.", + "examples": ["{\"type\": \"LogDetConeSquare\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "LogDetConeSquare" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The (vectorized) cone of symmetric positive semidefinite matrices, with `side_dimension` rows and columns. The entries of the upper-right triangular part of the matrix are given column by column (or equivalently, the entries of the lower-left triangular part are given row by row).", + "examples": ["{\"type\": \"PositiveSemidefiniteConeTriangle\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "PositiveSemidefiniteConeTriangle" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "DEPRECATED: use the Scaled set combinned with PositiveSemidefiniteConeTriangle instead.", + "required": ["side_dimension"], + "properties": { + "type": { + "const": "ScaledPositiveSemidefiniteConeTriangle" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The cone of symmetric positive semidefinite matrices, with side length `side_dimension`. The entries of the matrix are given column by column (or equivalently, row by row). The matrix is both constrained to be symmetric and to be positive semidefinite. That is, if the functions in entries `(i, j)` and `(j, i)` are different, then a constraint will be added to make sure that the entries are equal.", + "examples": ["{\"type\": \"PositiveSemidefiniteConeSquare\", \"side_dimension\": 2}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "PositiveSemidefiniteConeSquare" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "[x, y, z] ∈ {R³: x^{exponent} y^{1-exponent} ≥ |z|; x, y ≥ 0}", + "examples": ["{\"type\": \"PowerCone\", \"exponent\": 2.0}"], + "required": ["exponent"], + "properties": { + "type": { + "const": "PowerCone" + }, + "exponent": { + "type": "number" + } + } + }, { + "description": "[u, v, w] ∈ {R³: (u / exponent)^{exponent} (v / (1-exponent))^{1-exponent} ≥ |w|; u, v ≥ 0}", + "examples": ["{\"type\": \"DualPowerCone\", \"exponent\": 2.0}"], + "required": ["exponent"], + "properties": { + "type": { + "const": "DualPowerCone" + }, + "exponent": { + "type": "number" + } + } + }, { + "description": "If `activate_on=one`: (y, x) ∈ {0,1}×Rᴺ: y = 0 ⟹ x ∈ S, otherwise when `activate_on=zero`: (y, x) ∈ {0,1}×Rᴺ: y = 1 ⟹ x ∈ S.", + "examples": ["{\"type\": \"Indicator\", \"set\": {\"type\": \"LessThan\", \"upper\": 2.0}, \"activate_on\": \"one\"}"], + "required": ["set", "activate_on"], + "properties": { + "type": { + "const": "Indicator" + }, + "set": { + "oneOf": [{ + "$ref": "#/definitions/scalar_sets" + }, { + "$ref": "#/definitions/vector_sets" + }] + }, + "activate_on": { + "enum": ["one", "zero"] + } + } + }, { + "description": "(t, x) ∈ {R^{dimension}: t ≥ Σᵢ|xᵢ|}", + "examples": ["{\"type\": \"NormOneCone\", \"dimension\": 2}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "NormOneCone" + }, + "dimension": { + "type": "integer", + "minimum": 2 + } + } + }, { + "description": "(t, x) ∈ {R^{dimension}: t ≥ maxᵢ|xᵢ|}", + "examples": ["{\"type\": \"NormInfinityCone\", \"dimension\": 2}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "NormInfinityCone" + }, + "dimension": { + "type": "integer", + "minimum": 2 + } + } + }, { + "description": "(u, v, w) ∈ {R^{dimension}: u ≥ Σᵢ wᵢlog(wᵢ/vᵢ), vᵢ ≥ 0, wᵢ ≥ 0}", + "examples": ["{\"type\": \"RelativeEntropyCone\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "RelativeEntropyCone" + }, + "dimension": { + "type": "integer", + "minimum": 3 + } + } + }, { + "description": "(t, X) ∈ {R^{1+row_dim×column_dim}: t ≥ σ₁(X)}", + "examples": ["{\"type\": \"NormSpectralCone\", \"row_dim\": 1, \"column_dim\": 2}"], + "required": ["row_dim", "column_dim"], + "properties": { + "type": { + "const": "NormSpectralCone" + }, + "row_dim": { + "type": "integer", + "minimum": 1 + }, + "column_dim": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "(t, X) ∈ {R^{1+row_dim×column_dim}: t ≥ Σᵢ σᵢ(X)}", + "examples": ["{\"type\": \"NormNuclearCone\", \"row_dim\": 1, \"column_dim\": 2}"], + "required": ["row_dim", "column_dim"], + "properties": { + "type": { + "const": "NormNuclearCone" + }, + "row_dim": { + "type": "integer", + "minimum": 1 + }, + "column_dim": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The set corresponding to a mixed complementarity constraint. Complementarity constraints should be specified with an AbstractVectorFunction-in-Complements(dimension) constraint. The dimension of the vector-valued function `F` must be `dimension`. This defines a complementarity constraint between the scalar function `F[i]` and the variable in `F[i + dimension/2]`. Thus, `F[i + dimension/2]` must be interpretable as a single variable `x_i` (e.g., `1.0 * x + 0.0`). The mixed complementarity problem consists of finding `x_i` in the interval `[lb, ub]` (i.e., in the set `Interval(lb, ub)`), such that the following holds: 1. `F_i(x) == 0` if `lb_i < x_i < ub_i`; 2. `F_i(x) >= 0` if `lb_i == x_i`; 3. `F_i(x) <= 0` if `x_i == ub_i`. Classically, the bounding set for `x_i` is `Interval(0, Inf)`, which recovers: `0 <= F_i(x) ⟂ x_i >= 0`, where the `⟂` operator implies `F_i(x) * x_i = 0`.", + "examples": ["{\"type\": \"Complements\", \"dimension\": 2}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Complements" + }, + "dimension": { + "type": "integer", + "minimum": 2 + } + } + }, { + "description": "The set {x in Z^d} such that no two elements in x take the same value and dimension=d.", + "examples": ["{\"type\": \"AllDifferent\", \"dimension\": 2}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "AllDifferent" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The set `{x in Z^d}` where `d = length(w)`, such that each item `i` in `1:d` of weight `w[i]` is put into bin `x[i]`, and the total weight of each bin does not exceed `c`.", + "examples": ["{\"type\": \"BinPacking\", \"capacity\": 3.0, \"weights\": [1.0, 2.0, 3.0]}"], + "required": ["capacity", "weights"], + "properties": { + "type": { + "const": "BinPacking" + }, + "capacity": { + "type": "number" + }, + "weights": { + "type": "array", + "items": { + "type": "number" + } + } + } + }, { + "description": "The set `{x in {1..d}^d}` that constraints `x` to be a circuit, such that `x_i = j` means that `j` is the successor of `i`, and `dimension = d`.", + "examples": ["{\"type\": \"Circuit\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Circuit" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The set `{x in Z^{d_1 + d_2 + ldots d_N}}`, where `x` is partitioned into `N` subsets (`{x_1, ldots, x_{d_1}}`, `{x_{d_1 + 1}, ldots, x_{d_1 + d_2}}` and so on), and at least `n` elements of each subset take one of the values in `set`.", + "examples": ["{\"type\": \"CountAtLeast\", \"n\": 1, \"partitions\": [2, 2], \"set\": [3]}"], + "required": ["n", "partitions", "set"], + "properties": { + "type": { + "const": "CountAtLeast" + }, + "n": { + "type": "integer", + "minimum": 0 + }, + "partitions": { + "type": "array", + "items": { + "type": "integer" + } + }, + "set": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, { + "description": "The set `{(n, x) in Z^{1+d}}`, such that `n` elements of the vector `x` take on of the values in `set` and `dimension = 1 + d`.", + "examples": ["{\"type\": \"CountBelongs\", \"dimension\": 3, \"set\": [3, 4, 5]}"], + "required": ["dimension", "set"], + "properties": { + "type": { + "const": "CountBelongs" + }, + "dimension": { + "type": "integer", + "minimum": 1 + }, + "set": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, { + "description": "The set `{(n, x) in Z^{1+d}}`, such that the number of distinct values in `x` is `n` and `dimension = 1 + d`.", + "examples": ["{\"type\": \"CountDistinct\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "CountDistinct" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The set `{(c, y, x) in Z^{1+1+d}}`, such that `c` is strictly greater than the number of occurances of `y` in `x` and `dimension = 1 + 1 + d`.", + "examples": ["{\"type\": \"CountGreaterThan\", \"dimension\": 3}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "CountGreaterThan" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The set `{(s, d, r, b) in Z^{3n+1}}`, representing the `cumulative` global constraint, where `n == length(s) == length(r) == length(b)` and `dimension = 3n + 1`. `Cumulative` requires that a set of tasks given by start times `s`, durations `d`, and resource requirements `r`, never requires more than the global resource bound `b` at any one time.", + "examples": ["{\"type\": \"Cumulative\", \"dimension\": 10}"], + "required": ["dimension"], + "properties": { + "type": { + "const": "Cumulative" + }, + "dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "Given a graph comprised of a set of nodes `1..N` and a set of arcs `1..E` represented by an edge from node `from[i]` to node `to[i]`, `Path` constrains the set `(s, t, ns, es) in (1..N)times(1..E)times{0,1}^Ntimes{0,1}^E`, to form subgraph that is a path from node `s` to node `t`, where node `n` is in the path if `ns[n]` is `1`, and edge `e` is in the path if `es[e]` is `1`. The path must be acyclic, and it must traverse all nodes `n` for which `ns[n]` is `1`, and all edges `e` for which `es[e]` is `1`.", + "examples": ["{\"type\": \"Path\", \"from\": [1, 1, 2, 2, 3], \"to\": [2, 3, 3, 4, 4]}"], + "required": ["from", "to"], + "properties": { + "type": { + "const": "Path" + }, + "from": { + "type": "array", + "items": { + "type": "integer" + } + }, + "to": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, { + "description": "The set `{x in R^d}` where `d = size(table, 2)`, such that `x` belongs to one row of `table`. That is, there exists some `j` in `1:size(table, 1)`, such that `x[i] = table[j, i]` for all `i=1:size(table, 2)`.", + "examples": ["{\"type\": \"Table\", \"table\": [[1, 1, 0], [0, 1, 1]]}"], + "required": ["table"], + "properties": { + "type": { + "const": "Table" + }, + "table": { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + } + } + }, { + "description": "(z, f(x)) ∈ {R^{dimension}: z iff f(x) ∈ S}", + "examples": ["{\"type\": \"Reified\", \"set\": {\"type\": \"GreaterThan\", \"lower\": 0}}"], + "required": ["set"], + "properties": { + "type": { + "const": "Reified" + }, + "set": { + "oneOf": [{ + "$ref": "#/definitions/scalar_sets" + }, { + "$ref": "#/definitions/vector_sets" + }] + } + } + }, { + "description": "x ∈ {R^d: x_i ∈ [lower_i, upper_i]}", + "examples": ["{\"type\": \"HyperRectangle\", \"lower\": [0, 0], \"upper\": [1, 1]}"], + "required": ["lower", "upper"], + "properties": { + "type": { + "const": "HyperRectangle" + }, + "lower": { + "type": "array", + "items": { + "type": "number" + } + }, + "upper": { + "type": "array", + "items": { + "type": "number" + } + } + } + }, { + "description": "The (vectorized) cone of Hermitian positive semidefinite matrices, with non-negative side_dimension rows and columns.", + "examples": ["{\"type\": \"HermitianPositiveSemidefiniteConeTriangle\", \"side_dimension\": 3}"], + "required": ["side_dimension"], + "properties": { + "type": { + "const": "HermitianPositiveSemidefiniteConeTriangle" + }, + "side_dimension": { + "type": "integer", + "minimum": 1 + } + } + }, { + "description": "The p-norm cone (t, x) ∈ {R^d : t ≥ (Σᵢ|xᵢ|^p)^(1/p)}.", + "examples": ["{\"type\": \"NormCone\", \"dimension\": 3, \"p\": 1.5}"], + "required": ["dimension", "p"], + "properties": { + "type": { + "const": "NormCone" + }, + "dimension": { + "type": "integer", + "minimum": 1 + }, + "p": { + "type": "number" + } + } + }, { + "description": "The set in the `set` field, scaled such that the inner product of two elements in the set is the same as the dot product of the two vector functions. This is most useful for solvers which require PSD matrices in _scaled_ form.", + "examples": ["{\"type\": \"Scaled\", \"set\": {\"type\": \"PositiveSemidefiniteConeTriangle\", \"side_dimension\": 2}}"], + "required": ["set"], + "properties": { + "type": { + "const": "Scaled" + }, + "set": { + "$ref": "#/definitions/vector_sets" + } + } + }] + } + } +} diff --git a/schemas/mof.1.schema.json b/schemas/mof.1.schema.json index dd73a68..ef3b274 100644 --- a/schemas/mof.1.schema.json +++ b/schemas/mof.1.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/schema#", - "$id": "https://jump.dev/MathOptFormat/schemas/mof.1.6.schema.json", + "$id": "https://jump.dev/MathOptFormat/schemas/mof.1.7.schema.json", "title": "The schema for MathOptFormat", "type": "object", "required": ["version", "variables", "objective", "constraints"], @@ -11,7 +11,7 @@ "required": ["minor", "major"], "properties": { "minor": { - "enum": [0, 1, 2, 3, 4, 5, 6] + "enum": [0, 1, 2, 3, 4, 5, 6, 7] }, "major": { "const": 1 @@ -191,11 +191,10 @@ }, "NonlinearTerm": { "description": "A node in an expresion graph representing a nonlinear function.", - "type": "object", - "required": ["type"], "oneOf": [{ "description": "Unary operators", - "required": ["args"], + "type": "object", + "required": ["type", "args"], "properties": { "type": { "enum": [ @@ -284,7 +283,8 @@ } }, { "description": "Binary operators", - "required": ["args"], + "type": "object", + "required": ["type", "args"], "properties": { "type": { "enum": [ @@ -311,7 +311,8 @@ } }, { "description": "N-ary operators", - "required": ["args"], + "type": "object", + "required": ["type", "args"], "properties": { "type": { "enum": ["+", "-", "*", "ifelse", "min", "max"] @@ -327,7 +328,8 @@ }, { "description": "A real-valued numeric constant", "examples": ["{\"type\": \"real\", \"value\": 1.0}"], - "required": ["value"], + "type": "object", + "required": ["type", "value"], "properties": { "type": { "const": "real" @@ -339,7 +341,8 @@ }, { "description": "A complex-valued numeric constant", "examples": ["{\"type\": \"complex\", \"real\": 1.0, \"imag\": 2.0}"], - "required": ["real", "imag"], + "type": "object", + "required": ["type", "real", "imag"], "properties": { "type": { "const": "complex" @@ -354,7 +357,8 @@ }, { "description": "A reference to an optimization variable", "examples": ["{\"type\": \"variable\", \"name\": \"x\"}"], - "required": ["name"], + "type": "object", + "required": ["type", "name"], "properties": { "type": { "const": "variable" @@ -366,7 +370,8 @@ }, { "description": "A pointer to a (1-indexed) element in the `node_list` field in a nonlinear function", "examples": ["{\"type\": \"node\", \"index\": 2}"], - "required": ["index"], + "type": "object", + "required": ["type", "index"], "properties": { "type": { "const": "node" @@ -376,6 +381,14 @@ "minimum": 1 } } + }, { + "description": "A reference to an optimization variable", + "examples": ["\"x\""], + "type": "string" + }, { + "description": "A real-valued numeric constant", + "examples": [1.0], + "type": "number" }] }, "scalar_functions": {