-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
This is an initial proposal, and will be updated in the future to conform to contribution guidelines for Active Vocabularies
This proposal is for the addition of an "equation" keyword to the JSON Schema specification. This keyword allows expressing complex validation logic using a human-readable, regex-inspired syntax called Mathex. This simplifies validation rules, especially those involving multiple properties, and reduces the reliance on complex, language-specific code.
Motivation:
Current JSON Schema validation primarily focuses on individual properties (type, range, format, etc.). Expressing complex relationships between properties often requires external validation code or custom keywords. This can lead to:
- Verbosity and Maintainability Issues: Complex validation logic embedded in external code becomes difficult to understand, debug, and maintain.
- Portability Challenges: Language-specific validation code hinders schema reuse across different environments and technologies.
- Error-Prone Implementation: Manually implementing complex validation rules increases the risk of errors
Relying on external code for validation logic is exactly what a schema is meant to resolve.
Furthermore, there have been many open issues related to numeric validation beyond the very limited type, min, max, etc. keywords. These almost always end up being some sort of equation or dependent logic.
Proposed Solution:
The equation keyword addresses many of these challenges by introducing Mathex, a concise and portable validation language, directly within the schema.
1. equation Keyword for Single Properties:**
For individual properties, the "equation" keyword takes a string representing a Mathex equation. The value of the property being validated is substituted for the variable 'A' in the equation.
{
"type": "object",
"properties": {
"age": {
"type": "integer",
"equation": "A > 0 && A % 2 == 0" // Validates that age is greater than 0 and even
}
}
}2. equation Keyword for Objects (using an array):
For validating relationships between multiple properties within an object, the "equation" keyword is an array. The first element is a string representing the Mathex equation. Subsequent elements are strings containing relative JSON Pointers corresponding to the variables used in the equation, in order of appearance.
{
"type": "object",
"properties": {
"width": { "type": "number" },
"height": { "type": "number" },
"area": { "type": "number" }
},
"equation": [
"A == B * C", // The equation
"/area", // First variable (/area)
"/width", // Second variable (/width)
"/height" // Third variable (/height)
]
}3. Mathex Syntax and Semantics:
Mathex follows C++ operator precedence with the addition of '^' for exponentiation. It supports:
- Numbers: Numeric literals (e.g., 10, 3.14).
- Variables: Single uppercase letters (A, B, C, AA, BB, ...)
- Math Symbols: Standard operators (+, -, *, /, %, ^, <, >, <=, >=, ==, !=, &&, ||, etc.).
- Functions: Common math functions (min, max, abs, etc.).
- Parentheses: For controlling operator precedence.
For a more detailed understanding of what mathex proposes beyond what plain old high school algrebra provides, see a draft lua implementation here
4. Implementation and Validation:
JSON Schema validators would need to incorporate a Mathex interpreter. The validator would:
- Parse the "equation" into Reverse Polish Notation (RPN)
- Substitute property values (or resolved JSON Pointer values) for variables.
- Evaluate the equation.
- Validation fails if the equation evaluates to false. (false as in C++ false - which is 0)
5. Error Reporting:
Clear error messages should indicate the failed equation and involved properties, associating JSON Pointers with their corresponding variables.
Example: Complex Validation:
{
"type": "object",
"properties": {
"score": { "type": "integer" },
"bonus": { "type": "integer" },
"level": { "type": "integer" }
},
"equation": [
"(A + B) > 1000 && C >= 5", // Equation
"/score", // A = /score
"/bonus", // B = /bonus
"/level" // C = /level
]
}6. Aircraft Altitude Validation Example:
This example demonstrates validating an aircraft's altitude within a specified range using the equation keyword and ECEF coordinates. We'll assume a simplified Earth model where the Earth's radius is a constant, and altitude is simply the distance from the Earth's center minus the Earth's radius, with a minimum elevation of -500 feet and max of 500,000 feet.
{
"type": "object",
"properties": {
"x": { "type": "number", "description": "ECEF X coordinate (meters)" },
"y": { "type": "number", "description": "ECEF Y coordinate (meters)" },
"z": { "type": "number", "description": "ECEF Z coordinate (meters)" }
},
"equation": [
"((A^2 + B^2 + C^2)^(0.5) - 6371000) > -152.4 && ((A^2 + B^2 + C^2)^(0.5) - 6371000) < 152400",
"/x",
"/y",
"/z"
]
}Explanation:
- ECEF Coordinates: The
x,y, andzproperties represent the aircraft's position in the Earth-Centered, Earth-Fixed (ECEF) coordinate system in meters. - Earth's Radius:
6371000is a constant representing the Earth's radius in meters. This is a simplification; the Earth is not a perfect sphere. - Altitude Calculation:
(A^2 + B^2 + C^2)^(0.5)calculates the distance from the Earth's center to the aircraft. Subtracting the Earth's radius (6371000) gives the altitude. - Altitude Limits: The equation checks if the calculated altitude (in meters) is greater than -152.4 meters (-500 feet) and less than 152400 meters (500,000 feet).
- Variables and JSON Pointers:
A,B, andCin the equation correspond to the/x,/y, and/zproperties, respectively, as indicated by the JSON Pointers in the array.
Summary
- Improved Readability: Clear and concise validation logic.
- Enhanced Maintainability: Centralized validation rules.
- Increased Portability: Language-agnostic Mathex equation specfication.
- Reduced Development Time: Simplified validation, in easy to pick up terms.
- Backwards Compatibility: This proposal introduces a new keyword and doesn't impact existing JSON Schemas.