{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Refined Math Customer Program SDK v1",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "format": {
      "const": "refined.math.program"
    },
    "schemaVersion": {
      "const": 1
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 120
    },
    "parameters": {
      "type": "array",
      "maxItems": 32,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/$defs/name"
          },
          "minLength": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4096
          },
          "maxLength": {
            "type": "integer",
            "minimum": 1,
            "maximum": 4096
          }
        },
        "required": [
          "name"
        ]
      }
    },
    "state": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "kind": {
          "enum": [
            "binary",
            "integer",
            "permutation"
          ]
        },
        "size": {
          "$ref": "#/$defs/expression"
        },
        "lower": {
          "$ref": "#/$defs/expression"
        },
        "upper": {
          "$ref": "#/$defs/expression"
        }
      },
      "required": [
        "kind",
        "size"
      ]
    },
    "inputChecks": {
      "type": "array",
      "maxItems": 32,
      "items": {
        "$ref": "#/$defs/expression"
      }
    },
    "initialize": {
      "$ref": "#/$defs/block"
    },
    "evaluation": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "steps": {
          "$ref": "#/$defs/block"
        },
        "objective": {
          "$ref": "#/$defs/expression"
        },
        "violations": {
          "$ref": "#/$defs/expression"
        }
      },
      "required": [
        "steps",
        "objective",
        "violations"
      ]
    },
    "validation": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "steps": {
          "$ref": "#/$defs/block"
        },
        "valid": {
          "$ref": "#/$defs/expression"
        }
      },
      "required": [
        "steps",
        "valid"
      ]
    },
    "operators": {
      "type": "array",
      "minItems": 1,
      "maxItems": 16,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/$defs/name"
          },
          "steps": {
            "$ref": "#/$defs/block"
          }
        },
        "required": [
          "name",
          "steps"
        ]
      }
    },
    "goal": {
      "enum": [
        "find",
        "minimize",
        "maximize"
      ]
    },
    "outputs": {
      "type": "object",
      "maxProperties": 16,
      "additionalProperties": {
        "$ref": "#/$defs/expression"
      }
    }
  },
  "required": [
    "format",
    "schemaVersion",
    "name",
    "parameters",
    "state",
    "initialize",
    "evaluation",
    "validation",
    "operators",
    "goal"
  ],
  "$defs": {
    "name": {
      "type": "string",
      "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,31}$",
      "not": {
        "enum": [
          "size",
          "state",
          "__proto__",
          "constructor",
          "prototype"
        ]
      }
    },
    "expression": {
      "oneOf": [
        {
          "type": "integer",
          "minimum": -1000000000,
          "maximum": 1000000000
        },
        {
          "type": "string",
          "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,31}$"
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "const": "data"
            },
            {
              "$ref": "#/$defs/name"
            },
            {
              "$ref": "#/$defs/expression"
            }
          ],
          "minItems": 3,
          "maxItems": 3
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "const": "state"
            },
            {
              "$ref": "#/$defs/expression"
            }
          ],
          "minItems": 2,
          "maxItems": 2
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "const": "len"
            },
            {
              "type": "string"
            }
          ],
          "minItems": 2,
          "maxItems": 2
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "enum": [
                "random",
                "abs",
                "neg",
                "not"
              ]
            },
            {
              "$ref": "#/$defs/expression"
            }
          ],
          "minItems": 2,
          "maxItems": 2
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "enum": [
                "+",
                "-",
                "*",
                "/",
                "%",
                "min",
                "max",
                "==",
                "!=",
                "<",
                "<=",
                ">",
                ">=",
                "and",
                "or"
              ]
            },
            {
              "$ref": "#/$defs/expression"
            },
            {
              "$ref": "#/$defs/expression"
            }
          ],
          "minItems": 3,
          "maxItems": 3
        },
        {
          "type": "array",
          "prefixItems": [
            {
              "const": "if"
            },
            {
              "$ref": "#/$defs/expression"
            },
            {
              "$ref": "#/$defs/expression"
            },
            {
              "$ref": "#/$defs/expression"
            }
          ],
          "minItems": 4,
          "maxItems": 4
        }
      ]
    },
    "block": {
      "type": "array",
      "maxItems": 256,
      "items": {
        "$ref": "#/$defs/statement"
      }
    },
    "statement": {
      "oneOf": [
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "let": {
              "$ref": "#/$defs/name"
            },
            "value": {
              "$ref": "#/$defs/expression"
            }
          },
          "required": [
            "let",
            "value"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "set": {
              "$ref": "#/$defs/expression"
            },
            "value": {
              "$ref": "#/$defs/expression"
            }
          },
          "required": [
            "set",
            "value"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "swap": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/expression"
              },
              "minItems": 2,
              "maxItems": 2
            }
          },
          "required": [
            "swap"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "reverse": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/expression"
              },
              "minItems": 2,
              "maxItems": 2
            }
          },
          "required": [
            "reverse"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "if": {
              "$ref": "#/$defs/expression"
            },
            "then": {
              "$ref": "#/$defs/block"
            },
            "else": {
              "$ref": "#/$defs/block"
            }
          },
          "required": [
            "if",
            "then"
          ]
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "for": {
              "$ref": "#/$defs/name"
            },
            "from": {
              "$ref": "#/$defs/expression"
            },
            "to": {
              "$ref": "#/$defs/expression"
            },
            "do": {
              "$ref": "#/$defs/block"
            }
          },
          "required": [
            "for",
            "from",
            "to",
            "do"
          ]
        }
      ]
    }
  }
}
