{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://rulegraph.org/schema/rg-ast/v1.1/rg-ast-v1.1.schema.json",
  "title": "RuleGraph AST v1.1 (backward-compatible)",
  "type": "object",
  "oneOf": [
    { "required": ["sym"] }, { "required": ["const"] }, { "required": ["neg"] },
    { "required": ["add"] }, { "required": ["sub"] }, { "required": ["mul"] },
    { "required": ["div"] }, { "required": ["pow"] }, { "required": ["vec"] },
    { "required": ["call"] }, { "required": ["let"] }
  ],
  "properties": {
    "sym": { "type": "string", "minLength": 1 },
    "const": { "oneOf": [
      { "type": "number" },
      { "type": "integer" },
      { "type": "object", "required": ["rat"], "properties": {
          "rat": {
            "type": "object",
            "required": ["p","q"],
            "properties": { "p": { "type": "integer" }, "q": { "type": "integer", "minimum": 1 } },
            "additionalProperties": false
          }
        }, "additionalProperties": false
      }
    ]},
    "neg": { "$ref": "#/$defs/Node" },
    "add": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/Node" } },
    "sub": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/Node" } },
    "mul": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/Node" } },
    "div": {
      "type": "array", "minItems": 2, "maxItems": 2,
      "prefixItems": [{ "$ref": "#/$defs/Node" }, { "$ref": "#/$defs/Node" }],
      "items": false
    },
    "pow": {
      "type": "array", "minItems": 2, "maxItems": 2,
      "prefixItems": [{ "$ref": "#/$defs/Node" }, { "$ref": "#/$defs/Node" }],
      "items": false
    },
    "vec": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/Node" } },

    "call": {
      "type": "object",
      "required": ["fn","args"],
      "properties": {
        "fn": {
          "type": "string",
          "enum": [
            "norm","dot","cross",
            "abs","sign",
            "min","max","clamp","step",
            "mix","saturate"
          ]
        },
        "args": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/Node" } }
      },
      "additionalProperties": false
    },

    "let": {
      "type": "array", "minItems": 2, "maxItems": 2,
      "prefixItems": [
        { "type": "object", "required": ["sym"], "properties": { "sym": { "type": "string" } }, "additionalProperties": false },
        { "$ref": "#/$defs/Node" }
      ],
      "items": false
    }
  },
  "$defs": {
    "Node": {
      "type": "object",
      "oneOf": [
        { "required": ["sym"] }, { "required": ["const"] }, { "required": ["neg"] },
        { "required": ["add"] }, { "required": ["sub"] }, { "required": ["mul"] },
        { "required": ["div"] }, { "required": ["pow"] }, { "required": ["vec"] },
        { "required": ["call"] }, { "required": ["let"] }
      ]
    }
  },
  "additionalProperties": false
}
