Skip to main content

Predicates

The three predicate methods on OctetSdk.loc. All three are async (Swift) / suspend (Kotlin) and do not throw. Runtime problems surface as INDETERMINATE verdicts, not exceptions.

isWithin

The primary predicate. Reads as: "my currently provable location is inside region."

public func isWithin(
region: OctetRegion,
atTime: Date = Date()
) async -> OctetVerdict

Example

let v = await sdk.loc.isWithin(
region: .country(isoCode: "US"),
atTime: Date()
)
if v.result == .yes { ship(v.proof!) }

isOutside

Reads as: "my currently provable location is outside region."

public func isOutside(
region: OctetRegion,
atTime: Date = Date()
) async -> OctetVerdict
caution

isOutside is not !isWithin. An INDETERMINATE is not outside. The separate call lets the caller assert the negative claim and get a proof of the negative. A verifier can check that proof just as easily as a YES. Negating an INDETERMINATE would erase the difference between "I'm not inside" and "I can't tell".


contains

Reads from the device's perspective: "my location contains this point within tol meters."

public func contains(
center: LatLon,
tol: Meters,
atTime: Date = Date()
) async -> OctetVerdict

Mathematically equivalent to isWithin(region: .disc(center: center, radiusMeters: tol), atTime:). Kept as a distinct verb because the device-centric reading is the natural one for proximity use cases ("am I near the delivery dropoff", "did I arrive at the geofence").

Rolling your own

isWithin is the load-bearing primitive. contains is a thin one-liner over it. The same trick rolls custom predicates:

extension OctetLoc {
func isNear(_ center: LatLon, _ tol: Meters) async -> OctetVerdict {
await isWithin(region: .disc(center: center, radiusMeters: tol))
}
func isInsideAny(_ regions: [OctetRegion]) async -> OctetVerdict? {
for r in regions {
let v = await isWithin(region: r)
if v.result == .yes { return v }
}
return nil
}
}

Time semantics

All three predicates take an optional atTime. See Time Semantics for the live / historical / future regimes and the per-resolution validity windows. Default is "now". Future times beyond ±2 s come back INDETERMINATE / FUTURE_TIME.

See also