Generate the explicit MEOS object model (class lattice, methods, error contract)#10
Generate the explicit MEOS object model (class lattice, methods, error contract)#10estebanzimanyi wants to merge 1 commit into
Conversation
d0adfd4 to
b97fef8
Compare
b97fef8 to
4ec925f
Compare
Extend objectModel.dispatch to the complete editorial-member set, transcribed verbatim from PyMEOS RFC #94 §7 (AST-extracted 1:1 from the hand-written oracle; do not re-derive per §6): geo += minus, nearest_approach_distance (single-block); temporal restructured to the adopted per-concrete contract dispatch.temporal.{tfloat,tint,tbool,ttext}.<member> with always_/ever_(not_)equal, temporal_(not_)equal, at, minus (tbool: only temporal_(not_)equal/at/minus; no temporal distance — none in the oracle). Schema additions: scalarType field, argTransform += textsetMake, py:"list[str]"; attach_object_model passthrough unchanged. Verified: JSON valid, non-dispatch facets byte-identical, generator emits it, zero #10 test regression vs the prior tip (identical 20 passed; the lone parity failure is the pre-existing cross-file test-ordering issue, independent).
4ec925f to
6cd5d5b
Compare
Makes ecosystem-wide 100% parity provable at one point instead of asserted from per-PR isolation-green. meta/integration-train.json is the PR dependency DAG + per-wave gates + merge order; verify-train.sh composes the train and runs each wave's gate (PASS only when just-run green here, else BLOCKED with the exact gate it needs). Operationalizes MobilityDB discussion #895 (wave-based merge plan). Stacked on feat/object-model (the catalog anchor): Wave 0 verifies here (2699 fns, PR #10 21/21, from_mfjson + constructors uniform); Waves 1-3 are honestly gated on the MEOS-1.4 bump (the single universal unblock).
Makes ecosystem-wide 100% parity provable at one point instead of asserted from per-PR isolation-green. meta/integration-train.json is the PR dependency DAG + per-wave gates + merge order; verify-train.sh composes the train and runs each wave's gate (PASS only when just-run green here, else BLOCKED with the exact gate it needs). Operationalizes MobilityDB discussion #895 (wave-based merge plan). Stacked on feat/object-model (the catalog anchor): Wave 0 verifies here (2699 fns, PR MobilityDB#10 21/21, from_mfjson + constructors uniform); Waves 1-3 are honestly gated on the MEOS-1.4 bump (the single universal unblock).
Makes ecosystem-wide 100% parity provable at one point instead of asserted from per-PR isolation-green. meta/integration-train.json is the PR dependency DAG + per-wave gates + merge order; verify-train.sh composes the train and runs each wave's gate (PASS only when just-run green here, else BLOCKED with the exact gate it needs). Operationalizes MobilityDB discussion #895 (wave-based merge plan). Stacked on feat/object-model (the catalog anchor): Wave 0 verifies here (2699 fns, PR MobilityDB#10 21/21, from_mfjson + constructors uniform); Waves 1-3 are honestly gated on the MEOS-1.4 bump (the single universal unblock).
Makes ecosystem-wide 100% parity provable at one point instead of asserted from per-PR isolation-green. meta/integration-train.json is the PR dependency DAG + per-wave gates + merge order; verify-train.sh composes the train and runs each wave's gate (PASS only when just-run green here, else BLOCKED with the exact gate it needs). Operationalizes MobilityDB discussion #895 (wave-based merge plan). Stacked on feat/object-model (the catalog anchor): Wave 0 verifies here (2699 fns, PR MobilityDB#10 21/21, from_mfjson + constructors uniform); Waves 1-3 are honestly gated on the MEOS-1.4 bump (the single universal unblock).
|
Coordination note from a sibling session — proposing a third per-function facet for this PR's object model.
Grounded backing: a v4 mechanical classifier (~250 LOC, deterministic) has already been applied to the catalog this PR emits — it classifies 2,240 public-API functions into 6 streaming tiers with 97.4% mechanical coverage (2.6% ambiguous = 59 functions). The classifier output has already driven a working codegen wedge on MobilityFlink and MobilityKafka (1 PR each, OPEN, 57 generated Java classes × 2,097 methods compile clean against JMEOS PR #19). This RFC formalizes the classifier as a catalog facet so every binding consumes the same tier assignments, and resolves the 59 ambiguous corner cases + 2 streaming-semantic nuances per-function so the facet ships complete with zero ambiguity remaining. Motivation (one paragraph)The MEOS public API has 2,240 functions. The first per-engine streaming binding (MobilityFlink) currently hand-wires 10 distinct operators to support the 9 BerlinMOD benchmark queries — 0.4% API coverage by operator. A mechanical classification (the v4 streaming-relevance baseline, deterministic name + signature + role rules) lifts that ceiling to 97.4% covered (87% streamable, 9.7% I/O-meta, 0.6% honestly marked non-streamable; 2.6% / 59 functions ambiguous under the mechanical rules). This RFC adopts the v4 baseline as the catalog's VocabularyClosed 7-value set. Every public MEOS function has exactly one tier.
Classification rules (deterministic, 18 rules applied in order; first match wins)Each rule fires off
Full ordered rule list reproducible from the reference classifier; the catalog ships it as Per-function overridesTwo override sources: A. The 59 ambiguous cases (post-hoc deterministic resolution)
Total: 57 entries covering all 59 ambiguous functions. Post-override ambiguous count: 0. Net additions: +33 stateless · +4 bounded-state · +3 cross-stream · +7 sequence-only · +8 io-meta. B. The 2 streaming-semantic nuances (per-function semantic overrides)Functions where the mechanical tier is technically correct but a streaming engineer needs a different operational reading. The override exposes BOTH so codegen can pick by mode.
Both modes are valid; the catalog ships them as a JSON schema (proposed){
"functions": {
"eintersects_tgeo_geo": {
"objectModel": {
"role": "predicate",
"classes": ["TGeo"],
"dispatch": { /* D1 facet, unchanged */ },
"nullable": { /* D2 facet, unchanged */ },
"streamingSemantics": {
"tier": "bounded-state",
"tierConfidence": "high",
"classificationRule": "rule-10: ever-rel on 1 temporal",
"alternateMode": {
"tier": "windowed",
"modeKey": "streamingMode.eRelOverWindow",
"reasoning": "OR-fold over trajectory lifetime"
}
}
}
}
}
}For functions with no Generator integrationAdd to MEOS-API:
Adoption path
The Wave-1 PR is small: ~250 LOC classifier + ~150 LOC override JSON + one-line Reference artifacts
Happy to provide the JSON files / classifier source as a follow-up PR off |
What
Makes the implicit MEOS object model explicit as a first-class
pipeline stage, so every binding/engine (PyMEOS, JMEOS, MEOS.NET,
MobilityDuck, MobilitySpark, …) derives the identical class hierarchy
and methods from one mapping instead of re-curating the C prefix
convention by hand.
MEOS is C — no classes. The model is encoded by convention in (1) the
Temporal/TInstant/TSequence/TSequenceSetstruct family (templateaxis), (2) the
temptypediscriminator whose base type is the missingtemplate parameter (type-family axis), and (3) the function-name prefixes
that bind a function to the class it is a method of.
How (mirrors the PR #8 portable-aliases pattern)
meta/object-model.json— curated source of truth: thesingle-inheritance lattice (
Temporal → TAlpha/TNumber/TSpatial →leaves), the geometry/geodetic trait axis, the Box and
Collection companion hierarchies required to type the closed
algebra, the
errorCodecontract, and the irregularity worklist.Figure 7.1 "Hierarchy of spatiotemporal types",
doc/images/tspatial.svg):TSpatial → TGeo → {TGeometry, TGeography, TPoint → {TGeomPoint, TGeogPoint}}withTCbuffer/TNpoint/TPose/TRGeometryunderTSpatial.TGeois the broad parent of all PostGIS-derivedtypes (= the C
tgeo_type_allpredicate);TPointis added as anAPI-level intermediate under
TGeo(the figure omits it but thetpoint_*family must bind to a class). Class names use the manualspelling (
TGeo,TNpoint,TCbuffer,TPose,TRGeometry); Cprefixes unchanged. A test gates the model against the figure so the
reconciliation cannot regress.
parser/object_model.py+run.pystage 3 — derive the classtree and assign every catalog function to the class it is a method of
by longest-prefix match (the function is its own backing symbol —
equivalence by construction). Additive
idl["objectModel"];functions[]untouched. Per-function raisederrorCodes derived by astatic scan of the MobilityDB sources (direct
meos_error+ oneensure_*indirection), honestsource-unavailablewhen absent.object_model_parity.py— audits the derived lattice against thePyMEOS factory oracle (parsed, never hard-coded).
MobilityDB predicates /
MEOS_TEMPTYPE_CATALOG/ enums (TGeo gatedagainst
tgeo_type_all); a manual-figure gate; a parity gate(every divergence has a stated correction).
python3 tests/test_*.py,no pytest/libclang needed.
setup.pyalso fetchesmeos/src;docs/object-model.md+ README.Live result
2672functions → 72 classes; every class-method prefix is 100%classified (
temporal_137/137,tnumber_32/32,tgeo_28/28,tpoint_25/25,tgeometry_5/5,tcbuffer_14/14,tnpoint_20/20,all leaves/subtypes,
trgeo_37/37). The remaining functions arecross-type operators (the portable-aliases / RFC-920 domain), base
PostGIS/
datum_helpers and runtime — the object-model andportable-aliases models cleanly partition the API into methods vs
operators.
Parity vs PyMEOS: 18 concrete classes aligned, 41 divergences, 0
needs-correction (all explained by curated corrections). Error scan:
scanned, 359 functions with a derivedraisesset. All 16 + 5 testsgreen (incl. drift, manual-figure and parity gates).
Irregularities surfaced (corrections worklist, report-only)
MEOS: OM-M1 (the class
TGeois broad per the manual, but the Ctgeo_type()/tgeo_*API is narrower — rejects points); OM-M2(
tgeometry_type()misnomer); OM-M3 (TRGeometrybase =T_POSE≠name); OM-M4 (
talpha_typehas no class name); OM-M5 (tpose_to_tpointrename strain); OM-M6 (manual Figure 7.1 is partial — spatial-only,
no
TPoint; model is the superset); OM-M7 (tpcpoint/tpcpatchplanned but absent from master MEOS and the figure — out of the
drift-gated SoT until MEOS adds them; derived automatically once
present). PyMEOS: OM-P1/P3/P4/P5/P6/P7 (missing 6 leaves, the full
Collection hierarchy, the
TSpatial/TGeoabstracts, dummyconstructors, shapely-base inconsistency, ad-hoc
bearing()).Fixes land as separate PRs in those repos by their own sessions.
Notes
master(per request); independent of feat: canonical portable bare-name mapping as the codegen source of truth #8/docs: cross-repo handoff brief for consuming meos-api.json artifacts #9.cbuffer/npoint/pose/rgeoare fullleaf classes and in scope;
trgeometryuser-facing,trgeo_notnormalized.
meos-api.jsonvsmeos-idl.jsonmismatchcorrected in the touched section.