Validation
A tool that will not show its working should not be trusted with yours. Octant's propagation is checked against NASA GMAT using real satellites' real TLEs, and the numbers are published whether they flatter or not.
Last run 10 August 2026 · reproducible with the scripts linked below.
The chain
Octant runs Orekit compiled to JavaScript. Trust in a number therefore needs two links, not one — and they are checked separately:
| Link | Question | Result |
|---|---|---|
| Browser ≡ native | Does compiling Orekit to JavaScript change any answer? | Identical to every digit printed |
| Orekit ≈ GMAT | Does Orekit agree with an independent, NASA-built tool? | ≤ 7.3 m over 24 h |
The first link matters because it is the unusual thing Octant does. IEEE-754 arithmetic is identical on a JVM and in a browser engine, and the measurements say so: the same case run natively and in the browser returns the same position to every digit reported, for analytical and numerical propagation alike.
Against GMAT, on real satellites
GMAT is NASA's General Mission Analysis Tool — open source, used for real mission design, and entirely independent of Orekit. Both were given the same real TLE, fetched from Celestrak, and asked to propagate 24 hours with SGP4.
| Satellite | Regime | Model | Mean | Max | Speed | Implied Δt |
|---|---|---|---|---|---|---|
| ISS (ZARYA) | 420 km, 51.6° | SGP4 | 6.60 m | 7.26 m | 7.66 km/s | 0.86 ms |
| Landsat 8 | 705 km SSO | SGP4 | 6.43 m | 7.08 m | 7.50 km/s | 0.86 ms |
| IUS R/B (1) | GTO, e = 0.712 | DeepSDP4 | 3.12 m | 9.21 m | 3.56 km/s | 0.90 ms |
| TDRS 3 | GEO | DeepSDP4 | 2.85 m | 3.10 m | 3.07 km/s | 0.93 ms |
1,442 samples each, one per minute across a full day. Four orbits spanning low Earth orbit, a geostationary transfer orbit and GEO — and both the near-Earth (SGP4) and deep-space (SDP4) branches of the model. Seven metres on a 6,800 km orbit is about one part in a million.
Why SGP4 for the comparison
Deliberately. A TLE plus the SGP4 model determine the answer completely: there is no force model, integrator tolerance or gravity field for two tools to disagree about legitimately. Any difference that remains is implementation — which is the only thing worth measuring in a cross-check. Comparing numerical propagators instead would mostly measure how similarly the two were configured.
What the residual is
Not a propagation disagreement. It is a sub-millisecond time-tag offset, and the four cases above are what establish it.
The difference does not grow over the day, which already rules out genuine divergence. What it does instead is scale with orbital speed: divide each position difference by the satellite's velocity and the result is the same across all four orbits — 0.86, 0.86, 0.90 and 0.93 milliseconds — even though those orbits differ in speed by a factor of 2.5, in eccentricity from 0.0004 to 0.712, and run through two different branches of the model.
A propagation difference would not behave that way. A constant time offset would, and does: the two tools place the satellite in the same place at times that differ by about 0.9 ms, most likely a convention in converting the TLE epoch or in leaving the TEME frame. 0.9 ms of clock is 7 m in low Earth orbit and 3 m at GEO, which is precisely the pattern measured.
This has not been chased to its source, and it is stated rather than rounded away. But it is now an explained residual with a testable signature, not an unexplained one.
The numerical propagator, on the same gravity field
The comparison above is silent about spherical-harmonic gravity, by construction — SGP4 has none. So here is the other half: a full numerical propagation, run in both tools, on the identical gravity field.
That last part is the whole difficulty. Orekit ships eigen-6s and GMAT ships JGM-2, so propagating in each and comparing would mostly measure the difference between two geodesy products — a fact about the world, not about either implementation, and the easy number to mistake for a validation. GMAT's own coefficient file is therefore converted into the format Orekit reads, and both tools integrate the same 2,553 coefficients with the same GM and the same reference radius.
| Case | Orbit | Median | Mean | Max | First hour → last |
|---|---|---|---|---|---|
| LEO | 700 km, near-circular | 0.10 m | 0.83 m | 4.83 m | 0.62 → 0.77 m |
| GTO | 200 × 20,000 km | 0.008 m | 0.09 m | 6.53 m | 0.42 → 0.51 m |
JGM-2 truncated to 20×20, gravity only, 24 hours, sampled every 60 s. GMAT: RungeKutta89 at 1e-12 accuracy. Orekit: Dormand-Prince 853 at 1 mm position tolerance. The initial state is taken from GMAT's own first report row, so element conversion is not in the comparison. 2,299 and 1,485 samples.
What is deliberately left out
Drag, solar radiation pressure, third bodies and tides. Each depends on a model the two tools do not share — an atmosphere, a flux history, a spacecraft area — so including them would measure how similarly two people configured two programs, which is the criticism a cross-check has to be immune to. Gravity alone is the part where "the same inputs" can actually be guaranteed.
What the residual is, and is not
It does not grow. Mean disagreement over the first hour and the last hour of the day differ by about 0.1 m in both cases, and the medians — 10 cm and 8 mm — sit far below the maxima. A force-model disagreement compounds; this does not, which places it with frame realisation and report rounding rather than with the physics.
The maxima land at perigee in the GTO case, where the spacecraft is fastest and any sub-millisecond difference in time-tagging buys the most metres — the same signature the SGP4 comparison above identifies, arriving by the same route.
What remains legitimately different is the Earth-fixed frame the harmonics are evaluated in: Orekit uses ITRF through IERS 2010 conventions with earth-orientation data applied, GMAT its own realisation. That is not a bug in either tool, and it is why this section reports a number rather than asserting a pass.
Run it: benchmark/scripts/validate-forcemodel.sh, after
GmatConsole.exe cases/leo_numerical.script. The field conversion is
benchmark/scripts/cof-to-gfc.py, and it prints a coefficient count against
the number a full field of that degree must contain, because a silently truncated
gravity field would look like a small disagreement rather than like a broken input.
What this does not establish
- The SGP4 comparison is not a validation of the interactive propagator — and neither is the numerical comparison above it. The tool's sliders use Eckstein-Hechler — mean elements, J2–J6, no drag, no solar radiation pressure, no third body. It is fast, and it is approximate. Against a full numerical force model it drifts about 3.3 km over 24 hours in low Earth orbit. That number is the honest cost of an instant answer, and the tool always names the model it used.
- Agreement is not accuracy. Two tools agreeing means they implement the same model consistently. SGP4 itself is only good to roughly a kilometre against reality, and degrades with age of the TLE.
- The Moon and Mars are unvalidated. Gravity fields are the real measured ones — GRGM660PRIM and jgm85f01 — but no independent cross-check has been run, and the body-fixed frames use the IAU rotation model without libration terms (roughly 600 m on the lunar surface).
- Eclipse geometry is unvalidated. Conical umbra, sanity-checked against physics — a dawn–dusk sun-synchronous orbit comes out fully sunlit, an ISS-like orbit 39.4% against a real 35–38% — but not compared with another tool.
The analyses, and what each one is checked against
The orbit is the part GMAT can arbitrate. Everything built on top of it — link budgets, data budgets, coverage, manoeuvre costs — is checked instead against closed forms, published figures, and invariants that a wrong implementation cannot satisfy. Those are weaker than an independent tool and stronger than nothing, and the difference is worth being explicit about.
Run automatically, against the shipped bundle
Seventeen suites in benchmark/scripts/, run by check-all.sh against
the compiled Orekit build rather than the Java source — TeaVM is a translation step that
can drop things, and the compiled file is what ships.
| Suite | What it asserts |
|---|---|
| DOM contract | every element id the code reaches for exists in the page |
| Time axis | index → time → index round-trips, times increase strictly across phase and burn seams, and no consumer assumes an even sample grid — Apollo's steps run 29.4 s to 1563.4 s apart, so an even grid is wrong by up to 40.9 h |
| Central-body change | a 100 km lunar orbit expressed about the Earth stays at lunar-orbit radius from the Moon at every sample while its Earth distance sweeps 400 000 km |
| Surface points | a site on the Moon drawn in Earth's frame holds one lunar radius from the Moon across a full month — worst error 0.6 km on 1737.4 km; the local vertical is the geodetic normal, 0.192° off radial at 45° latitude |
| Apollo | the four-phase chain reaches lunar orbit: 54 km periapsis, still in orbit after 3.24 days |
| LEO→GEO | 4258 m/s total against a published ~4260, with the residual 0.82° of inclination left visible rather than tuned away |
| Propagator choice | each theory is used where it is valid and refuses where it is not, and a refusal is reported rather than silently substituted |
| The flown flyby hyperbolae | four encounter scenarios hand the entry state to the engine and propagate the hyperbola, rather than replaying a table. Each must come out hyperbolic (e = 1.33 to 5.01 — an elliptical one would be a capture drawing a plausible curve), must reach the closest approach Horizons measured (0.00–0.12%), and must reach it at the measured time, which a hyperbola of the wrong phase would not. Against Horizons across the whole window the two-body arc holds to 80 km at Uranus and 12 466 at Jupiter, worst at the edges where the Sun's pull dominates |
| The science encounters | imported from JPL Horizons — Voyager 2's own trajectory and each moon's, differenced — because the moons are not in DE440 and the tour does not model the flyby hyperbolae. It is what judges the reconstruction: predicted flyby distances of 9.67, 2.60 and 4.20 planet radii against Horizons' 10.09, 2.67 and 4.19, with nothing fitted to them. Every closest approach must also fall inside its search window, after a 36-hour window reported Callisto at 676 000 km when the real encounter was 215 028 km eight hours earlier |
| Voyager 2's Grand Tour | reconstructed from five encounter dates and DE440, then checked against the mission rather than against itself: the launch energy comes out at C3 = 104.5 km²/s² against the ~103 a Titan IIIE-Centaur delivered, and the flyby distances the physics requires are 9.67, 2.60 and 4.20 planet radii against Voyager 2's ~10, ~2.7 and ~4.2. The v-infinity mismatches at each encounter must stay inside a deterministic-manoeuvre budget (112, 136 and 14 m/s on 8–15 km/s), and the launch orbit alone must fall short of Neptune — 6.4 AU against 30 |
| The Grand Tour as one chain | the legs and the flybys are joined at the spheres of influence and flown as eight phases, so the test is whether the arc reaches the planets at all: 0.72, 0.16, 0.11 and 0.03 Gm at the sampled minimum, for 369 m/s of departure and 228 m/s of approach corrections across 12.2 years. The builder refuses to write a chain that misses — it once reported success while sailing 92 Gm wide of Saturn, because “the worker flew it” meant only that nothing threw. Two of the four faults behind that were in the measurement rather than the mission: burns expressed in the frame of the phase they left instead of the one they arrive in, and sample times assumed uniform when the worker samples per phase |
| Voyager 2 against JPL Horizons | the reconstruction held against the trajectory actually flown, 886 heliocentric samples every 5 days across the twelve years. Median separation 0.04 Gm, worst 0.33 — 0.00% and 0.07% of the distance from the Sun — best-fit time shift 0 days. The four encounter states are baked from Horizons, so the arcs meet at the planets by construction; what is unpinned is the cruise, and mid-leg the error is 88, 160, 11 and 130 Mm, against 850, 796, 808 and 273 when every leg was two-body. The legs are integrated with the four giants pulling, in a frame whose origin is the central body, and aimed as they are flown — a conic aimed at Jupiter and then integrated lands 30 Gm away by Saturn. The last factor of four came from neither: the sampling pass carried the state from a phase's start to its first sample under the WRONG theory, three days of two-body just outside a sphere of influence, worth 16 m/s and 890 Mm by the end of the leg — the drawn arc and the flown arc differing, which is now 0 Mm |
| Gravity assist | a flyby cannot change the spacecraft's speed relative to the planet, only rotate it — measured on a real Earth‑to‑Venus leg as 4.862 km/s in and 4.862 km/s out, a difference of zero, while the heliocentric speed gains 1.756 km/s and the aphelion moves 1.015 → 1.263 AU. The deflection is checked against sin(δ/2) = 1/e, that flying closer turns further, and that the gain stays inside twice the planet's orbital speed |
| Satellite catalogue | every baked element set is propagated through the engine, its checksums verified, and its period cross-checked against its own semi-major axis by Kepler's third law. Each entry declares a regime as a field, and the orbit must match that regime's altitude AND inclination band — because one entry turned out to be a different satellite from the one requested, and another was matched into the wrong band by a word in its description |
| Spot checks | the closed-form and invariant comparisons below, re-run on every build rather than measured once: free-space path loss and dish gain against the textbook formulae and against their own doubling invariants (exactly 6.02 dB either way), the bandwidth limit that a power-only budget once ignored, the Doppler sign, the Apollo CSM and ISS masses derived from their parts lists, the CSM tank through the rocket equation, and vis-viva |
| The flown Earth‑to‑Mars mission | the shipped five-phase chain is flown from the elements and burn in the file: it must start in Earth orbit, change central body to the Sun and then to Mars, deliver the spacecraft to within a sphere of influence of Mars, and pass above the surface at about the 500 km its aim was solved for — 509 km measured. The note's claim that an untargeted burn would miss by millions of kilometres is checked too, since that is the whole argument for targeting |
| Lambert, the Mars window & the shipped transfer | the transfer solver reproduces a known orbit's own velocities to 0.0000 m/s at both ends, and the textbook Hohmann between 1.000 and 1.524 AU to within 0.4 m/s (Δv 2.946 and 2.650 km/s against a published 2.945 and 2.649). Flying the solved departure state arrives at Mars with a 0 km miss, and a scan over departure dates finds the real 2026 window — depart 2026-11-17, 270 days, v-infinity 3.44 km/s — which nothing in the tool was told. The two ends of the mission are checked against published figures as well: trans‑Mars injection from a 200 km parking orbit at 3700 m/s against ~3.6 km/s, and Mars capture into a 500 × 20 000 km ellipse at 1167 m/s against ~1 km/s — with the invariants that make the plausible mistakes fail: the burn must cost more than v‑infinity alone and less than escaping first, and capture at Earth must differ from capture at Mars. The shipped Earth‑to‑Mars scenario is then re-solved from its own epoch and duration: the six elements in the file must BE that solution (worst relative gap 4.7×10−7), its note must quote the departure v-infinity the transfer really has, and flying it must arrive at Mars |
| Heliocentric | the Sun as a central body, against figures from outside the tool: a circular orbit at 1 AU takes 365.257 days against the 365.256-day sidereal year, Earth's eccentricity sweeps 0.9833–1.0167 AU, and one year later the orbit closes to 1401 km — 0.001% of 1 AU. The mean-element theories are refused with a reason, since a point mass has no oblateness for them to model, and Earth's harmonic field survives the switch |
| Disposal manoeuvres | the deorbit and re-orbit ΔVs the compliance card quotes are flown through the shipped worker, not compared against a second formula: 99.3 m/s puts a 400 km circular orbit's perigee at 60.0 km exactly, and the IADC re-orbit raises apogee by its full 248 km clearance. At inclination J2 must move the achieved perigee down and never up — 14.3 km low at 28.5°, and the card's quoted allowance must cover it |
| Finite burns | propellant matches the rocket equation to 4.7e-13 kg; gravity loss falls as thrust rises (82.13 m/s lost of 100 at 40 N, 0.02 at 40 kN); and finite-burn reporting never describes an impulse it did not fly |
Closed-form and invariant spot checks
Measured against textbook formulae or against a quantity the same run computes another way. Six of these are now re-run on every build by the spot-check suite above — the two radio figures, both derived masses, the CSM tank and vis-viva. Two files had to be split out of the application before that was possible, because the arithmetic lived inside code that needs a browser to load.
Four are still measured-on-a-date and are marked below. The exported velocity, the data latency and the coverage figures come from orchestration — which spacecraft, which pass, which window — rather than from a formula, and reaching them from a headless check needs a harness that does not exist yet. Saying which is which matters more than the count.
| Quantity | Octant | Reference |
|---|---|---|
| Free-space path loss, 2.2 GHz at 1000 km | 159.30 dB | 159.3 dB, textbook |
| 3 m dish gain at 2.2 GHz | 34.58 dBi | ~34.4 dBi at 60% efficiency |
| Orbital speed, 620 km circular | 7551.9 m/s | 7543.2 m/s by vis-viva; the 0.12% is J2, which vis-viva omits |
| Exported velocity vs. its own trajectory (not re-run) | 0.0015 m/s | a 1 s central difference of the exported positions |
| Radial velocity at t=0, argument of perigee 90° | exactly 0 | 0 by definition at perigee |
| Apollo CSM full-tank ΔV | 2878 m/s | ~2800 m/s, published SPS capability |
| Apollo CSM wet mass, from its parts list | 30 301.5 kg | ~30 300 kg |
| ISS mass, from its parts list | 419 725.0 kg | 419 725 kg, published |
| Data latency when the link is not the constraint (not re-run) | 1 h 36 m 45 s | equals the station's longest gap exactly — the two are computed independently |
| Coverage with the Sun merely above the horizon (not re-run) | 15.3% | 29.1% on geometry alone: the terminator halves it |
What the analyses do not establish
- Conjunction screening is verified in the application, not on every build. It screens the spacecraft in one scenario against each other — never a public catalogue, which would need thousands of TLEs of varying age and would answer with a probability of collision rather than a miss distance. On the 24-satellite Walker template it finds the closest approaches to be cross-plane pairs at about 4700 km, which is what the geometry requires, and its refinement moves every approach 9–13 km closer than the sampled grid and never further.
- No independent tool has arbitrated any of them. A closed form checks arithmetic; it does not check that the right question was asked. The GMAT comparison above covers orbits, eclipse, access and lifetime — and nothing else on this page.
- The link budget is clear-sky, single-carrier and downlink only. No rain fade, polarisation mismatch, multipath, interference, or pointing loss from a real attitude error.
- Coverage and access for an off-body ground object are geometry. A lunar site's access is computed against its own local vertical, but nothing models what its terrain hides.
- The data budget's duty cycle is a proxy. It states how much of a window an instrument runs for, not when — the when would need a per-phase command.
- Component figures are representative, not datasheets. Panels, radios, batteries and thrusters carry numbers typical of their class, each with its source stated in the asset library. They are enough to size a mission and not enough to build one.
Reproduce it
Everything here is a script in the repository. Nothing is hand-copied into this page from a run that cannot be repeated.
benchmark/scripts/validate-sgp4.sh # fetch TLEs, run Orekit, diff against GMAT
GMAT-R2026a/bin/GmatConsole.exe cases/iss_sgp4.script
benchmark/scripts/run-native.sh # native Orekit timing baseline
benchmark/scripts/run-teavm.sh OctantApi # the browser build
Raw output lives in benchmark/results/. The GMAT scripts, the TLEs used
and the comparison harness are in benchmark/cases/ and
benchmark/src/.
← Back to the tool About → ↑ Top
Eclipse and ground-station access, against GMAT
Orbits were cross-checked against GMAT from the start; eclipse and visibility were not. That mattered more than it looked: a power budget begins with an eclipse fraction, so an unvalidated eclipse makes every number downstream of it a number with nothing underneath.
GMAT's EclipseLocator and ContactLocator were run over
one day of the same orbit, from the same epoch, with the same station. The 10° elevation
mask is expressed on our side as the half-cone that is a 10° mask at that
altitude — from Wertz, sin ρ = R/(R+h) and cos ε = sin η / sin ρ
— so neither tool is answering an easier question than the other.
Loading the measured numbers…
Every number in this section is read at page load from
data/validation-events.json — the same file the
golden tests assert against. A page whose numbers are typed
separately from the numbers the tests enforce is a page that goes quietly out of date.
Reproduce it:
GMAT-R2026a/bin/GmatConsole.exe -r benchmark/cases/eclipse_access.script
Raw GMAT reports are committed at benchmark/results/gmat_eclipse.txt and
gmat_contact.txt.
Orbital lifetime — what it is, and what it is not
Lifetime is estimated by integrating the orbit-averaged decay rate, King-Hele's first-order result for a near-circular orbit:
da/dt = −(Cd·A/m) · ρ(a) · √(µ·a)
The density ρ is Orekit's — Harris-Priester, the same atmosphere its numerical propagator uses — sampled around each revolution and averaged, because the day–night bulge changes it by a factor of two.
It is not a numerical propagation with drag. Octant has one, and it is the wrong tool here: a numerical run costs roughly 170× an analytical one, and a lifetime is measured in years. Integrating a decade that way would take longer than the mission.
Computed, for a 3U CubeSat
Cd = 2.2, area 0.03 m², mass 4 kg — a ballistic coefficient of 0.0165 m²/kg, circular, 51.6° inclination.
Note the vehicle these came from. Those are bare figures, typed. The 3U CubeSat in Octant’s own vehicle library derives 0.0204 m²/kg — it has four deployed panels and a camera, so it is both heavier and draggier, and it would decay sooner than the table says. Neither number is wrong; they describe different spacecraft. Deriving the coefficient from parts rather than typing it is what makes that difference visible instead of silent.
| Altitude | Octant | Typically quoted, mean solar activity |
|---|---|---|
| 300 km | 1.1 months | 2–3 months |
| 350 km | 3.2 months | 6–9 months |
| 400 km | 7.3 months | 1–2 years |
That comparison was wrong, and GMAT settled it. This page used to say Octant’s figures were “short, consistently and by roughly a factor of two” against the published column above. Given the same spacecraft — Cd·A/m = 0.0165 m²/kg — an independent tool reproduces our numbers instead:
Loading the measured numbers…
Lifetime cannot be a like-for-like check the way SGP4 was: GMAT does not implement Harris-Priester at all. So the question is not whether GMAT agrees to a digit but whether we sit inside the spread two respectable atmospheres produce — and we do, at 300 km and at 400 km, and within 7% at 350 km. At 400 km GMAT’s two atmospheres differ from each other by 41%, more than either differs from us.
A published lifetime table is only meaningful with its ballistic coefficient and its solar activity attached; the column above carried neither. The self-criticism was honest and it was wrong, which is a decent argument for checking against a tool rather than against a remembered range.
The uncertainty that dominates everything above — now measured
The solar cycle. This page used to assert that it dominated. It does, and here is by how much. Harris-Priester has no solar-activity input at all — one fixed table — so the same decay was run over Orekit’s NRLMSISE00, which does, at three points of the cycle.
Loading…
Two things fall out. The spread grows with altitude — a factor of 4 at 300 km, 10 at 400 km. And Harris-Priester turns out to track the mid-cycle case to within 5% at every altitude, so calling it “a fixed level on the high side” was wrong in the same way the factor-of-two claim was. It is essentially the mean.
NRLMSISE00 needs no space-weather file here, which is why this was affordable at all: Orekit drives it through a five-method interface, and that interface can be implemented with constants. The activity becomes an explicit input the caller chooses rather than a data file to bake and keep current. Constants rather than a predicted flux series on purpose — a prediction would give one confident answer for a launch date five years out, which is exactly the false precision worth avoiding.
What the averaging costs — the one thing GMAT could not tell us
GMAT averages the same kind of thing we do, so both tools could share an approximation error and agree beautifully. Isolating it needs the same spacecraft, the same epoch and the same atmosphere integrated two ways: Orekit’s numerical propagator with a real drag force and no averaging anywhere, against the King-Hele orbit-averaged loop Octant ships.
Loading…
Orbit-averaging over-predicts lifetime by 3.5% at 400 km, rising to 11% at 300 km. The sign is consistent and the trend is the right way round: the approximation assumes the orbit changes little over one revolution, and that weakens exactly where the decay per revolution grows. Over-predicting is also the safe direction for a disposal argument — it makes a 25-year claim harder to satisfy, not easier.
The numerical side is stepped one day at a time, so it is quantised to a whole day — at
300 km that is 4% of the answer and a real part of the 11%. Reproduce with
benchmark/scripts/validate-decay.sh.
So which uncertainty actually matters
Loading…
They are not the same size, and that is the practical conclusion of this whole section. The tool now shows a range rather than a number — not out of caution, but because the headline uncertainty is two orders of magnitude larger than the modelling ones, and a single figure to three digits would be a statement about arithmetic rather than about the spacecraft.
What is checked, and what is not
Checked: against GMAT at three altitudes with two independent atmospheres
— reproducible with GmatConsole.exe -r benchmark/cases/lifetime.script, raw
output committed at benchmark/results/gmat_lifetime.txt. The scaling also
behaves as it should, about ×2.5 per 50 km, which is the expected exponential.
Not checked: against a numerical propagation with drag over the full decay. The orbit-averaging approximation itself has not been isolated from the atmosphere it is averaging, and agreement with GMAT does not do that — both tools are being asked to average the same kind of thing.
Scope
Earth only — the Moon has no atmosphere and Mars is not implemented. Near-circular orbits only (e < 0.05): King-Hele's eccentric case is a different formula, and applying the circular one to a transfer orbit would produce a confident wrong answer rather than no answer. TLE objects are refused, because SGP4 elements carry their own B* drag term which this estimate would contradict rather than use.