classDiagram
class ObjOperator {
+evaluate(value1, operator, value2, constants_cache) bool
+resolve_operator(operator) str
+get_all_operators() dict
}
ObjOperator <.. ObjDecisionSwitch : uses
ObjOperator <.. ObjDecisionMatrix : uses
ObjOperator <.. ObjDecisionRuleset : uses
ObjOperator <.. ObjDecisionSegmentation : uses
Updated : 2026-03-31
Unified operator evaluation for all Axion decision engines.
Single source of truth — every engine delegates to
ObjOperator.evaluate() (Python-level) or
ObjOperator.resolve_operator() (alias resolution for
SQL-building engines like ObjDecisionSegmentation)
instead of implementing their own comparison logic.
| Symbol |
Word |
Aliases |
Description |
= |
EQUALS |
EQ, MATCH |
Equals (numeric or case-insensitive string) |
!= |
NOT_EQUALS |
NEQ, <> |
Not equals |
< |
LESS_THAN |
LT |
Less than |
> |
GREATER_THAN |
GT |
Greater than |
<= |
LESS_OR_EQUAL |
LTE, LE |
Less than or equal |
>= |
GREATER_OR_EQUAL |
GTE, GE |
Greater than or equal |
| Symbol |
Word |
Aliases |
Description |
>< |
IN |
@ |
Value is in comma-separated list |
!>< |
NOT_IN |
NOT IN |
Value is not in list |
| Symbol |
Word |
Aliases |
Description |
~ |
CONTAINS |
LIKE |
String contains substring |
!~ |
NOT_CONTAINS |
|
String does not contain |
| Symbol |
Word |
Aliases |
Description |
? |
IS_EMPTY |
IS NULL, ISNULL |
Value is null or empty string |
!? |
HAS_VALUE |
IS NOT NULL, ISNOTNULL |
Value exists and is not empty |
| Symbol |
Word |
Description |
~= |
RANGE |
Value within anchor +/- offset: (100,10) = 90-110 |
|
BETWEEN |
Value between two bounds: (1,10) = 1 to 10 inclusive |
| Symbol |
Word |
Aliases |
Description |
* |
OTHERWISE |
ELSE, DEFAULT, "" |
Always matches (use as last rule) |
When constants_cache is provided, values in IN, NOT_IN,
RANGE, and BETWEEN expressions are resolved from the cache.
constants = {"weekdays": "2,3,4,5,6"}
# weekdays expands to 2,3,4,5,6 then adds 7
evaluate("3", "><", "(weekdays,7)",
constants_cache=constants) # True
# Range with constants
constants = {"threshold": "100", "tolerance": "10"}
evaluate(105, "~=", "(threshold,tolerance)",
constants_cache=constants) # True
from ObjOperator import evaluate, resolve_operator
evaluate("YES", "=", "YES") # True
evaluate(42, "GREATER_THAN", 10) # True
evaluate("A", "><", "('A','B','C')") # True
evaluate("", "?", "") # True
evaluate("x", "*", "") # True
All three engines delegate automatically:
# ObjDecisionRuleset
rs.evaluate(value1, ">=", value2)
# ObjDecisionSwitch
sw.evaluate(value1, "GREATER_OR_EQUAL", value2)
# ObjDecisionMatrix
mx.evaluate(value1, "GTE", value2)
All produce the same result — the operator string is resolved
to the canonical name and evaluated identically.
- RuleName: Swap Critical
ConditionField: swap_percent
ConditionOperator: GREATER_THAN
ConditionValue: "80"
Outcome: CREATE_TICKET
- RuleName: Port Exposed
ConditionField: exposed_port
ConditionOperator: "><"
ConditionValue: "('3306','5432','27017')"
Outcome: CREATE_TICKET
- RuleName: No DNS
ConditionField: dns_record
ConditionOperator: "?"
ConditionValue: ""
Outcome: NOTIFY
| Engine |
File |
Purpose |
| ObjDecisionSwitch |
factory.core/ObjDecisionSwitch.py |
Tree-based branching decisions |
| ObjDecisionMatrix |
factory.core/ObjDecisionMatrix.py |
Two-axis grid lookup |
| ObjDecisionRuleset |
factory.core/ObjDecisionRuleset.py |
Priority-ordered rule evaluation |
| ObjHost |
factory.core/ObjHost.py |
Host reaction rules |
- Add the canonical name + aliases to
OPERATOR_ALIASES in ObjOperator.py
- Add the evaluation logic in
evaluate()
- Add tests in
test_ObjOperator.py
- All engines pick it up automatically
Updated : 2026-03-27