Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/paulch42/lean-spec/llms.txt

Use this file to discover all available pages before exploring further.

LeanSpec.FPL.Flight defines the central data entity capturing all information about a flight, with invariants that enforce consistency between related fields using dependent types. A flight is not merely a record — it is a proof-carrying structure: constructing a Flight value requires simultaneously discharging all the cross-field constraints that ensure the data is internally coherent. This module also introduces the infrastructure for flight identification and matching (used to correlate incoming messages with stored flights), flight time estimation, and a set of type classes that abstract over flight-like entities throughout the specification.
import LeanSpec.FPL.Field

open Temporal Core FPL.Field

namespace FPL

Flight Identification

FlightId

The flight identifier is the key used to match received flight information against already-known flights. It is derived from three pieces of information:
  • acid — the aircraft identification (call sign) from Field 7a.
  • adep — the departure aerodrome from Field 13a.
  • period — a time interval computed from the departure time (Field 13b) and the estimated flight duration (Field 16b).
structure FlightId where
  acid   : AircraftIdentification
  adep   : Option ADep
  period : Interval
deriving DecidableEq
Two flight identifiers match if they share the same aircraft identification, the same departure point, and have overlapping flight time intervals. Matching is intentionally approximate — information arrives from multiple sources and is not always perfectly consistent — so overlapping periods rather than equal periods are required.
def FlightId.match : FlightId → FlightId → Bool
  | ⟨a₁,d₁,p₁⟩, ⟨a₂,d₂,p₂⟩ => a₁ = a₂ ∧ d₁ = d₂ ∧ p₁ ∩ p₂ ≠ ∅

Type Classes for Flight-Like Entities

FlightTime

Any type that has an identifiable flight time period implements this class. The method period maps a value to the Interval representing the flight’s duration on a timeline.
class FlightTime (α: Type) where
  period : α → Interval

IsFlight

Any type from which a FlightId can be derived implements IsFlight. This requires a prior FlightTime instance — flight identification presupposes a knowable time period.
class IsFlight (α : Type) [FlightTime α] where
  idOf : α → FlightId

ToFlight

Any type from which a full Flight can be generated implements ToFlight. This is used by message types (particularly FPL) to produce the initial flight record when a new flight is added to the state.
class ToFlight (α : Type) where
  toFlight : α → Flight

Flight Time Estimation

When full flight information is not yet available, the flight period must be estimated conservatively to ensure messages are not incorrectly discarded.

maxFlightTime

The default maximum flight duration used when the estimated elapsed time is unknown. Set to 20 hours.
def maxFlightTime := Duration.oneHour * 20

maxRoundTripTime

For flights where the departure and destination aerodromes are the same (round trips), a shorter default maximum is used. Set to 6 hours.
def maxRoundTripTime := Duration.oneHour * 6

adepAdesFlightTime

Computes an estimated flight time interval from the departure time, the estimated flight duration (if known), and whether departure equals destination. The calculation doubles the TEET for non-round-trip flights (to allow for late arrivals) and caps against the appropriate maximum.
def adepAdesFlightTime (f13a : Field13a) (f13b : DTG) (f16a : Field16a) : Option Duration → Interval
  | none      => -- flight duration not known
                 .intervalOf f13b (if adepIsAdes f13a f16a then maxRoundTripTime else maxFlightTime)
  | some teet => -- flight duration known
                 if adepIsAdes f13a f16a then
                   .intervalOf f13b (min teet maxRoundTripTime)
                 else
                   .intervalOf f13b (min (teet * 2) maxFlightTime)

Flight Status

A flight progresses through a lifecycle, and its current position in that lifecycle is recorded as a status value.
inductive FlightStatus
  | filed      -- flight plan received and accepted
  | airborne   -- departure confirmed
  | cancelled  -- flight plan cancelled
  | completed  -- arrival confirmed
deriving DecidableEq
ConstructorMeaning
filedA FPL message has been received and the flight is stored
airborneA DEP message has been received confirming departure
cancelledA CNL message has been received
completedAn ARR message has been received confirming arrival

The Flight Structure

The Flight structure is the central entity of the specification. It accumulates all fields received across the sequence of messages for a flight, plus a lifecycle status. Field 22 is excluded: its sole purpose is to communicate changes, and those changes are incorporated into the other fields when a CHG message is processed.
structure Flight where
  status : FlightStatus
  f7     : Field7
  f8     : Field8
  f9     : Field9
  f10    : Field10
  f13    : Field13
  f15    : Field15
  f16    : Field16
  f17    : Option Field17
  f18    : Option Field18
  inv    : F8F15Level f8 f15 ∧
           F8F15Rule f8 f15 ∧
           F9F18Typ f9 f18 ∧
           F10F18Sts f10 f18 ∧
           F10F18Pbn f10 f18 ∧
           F10F18Z f10 f18 ∧
           F13F18Dep f13 f18 ∧
           F15F18Dle f15 f18 ∧
           F16F18Dest f16 f18 ∧
           F16F18Altn f16 f18 ∧
           F16F18Eet f16 f18 ∧
           F16F18Dle f16 f18 ∧
           F16F17Dest f16.f16a f17 ∧
           -- Field 17 is populated if and only if the flight is completed.
           f17.isSome ↔ status = .completed
deriving DecidableEq

Fields

FieldTypeDescription
statusFlightStatusCurrent lifecycle status
f7Field7Aircraft identification and optional SSR code
f8Field8Flight rules and type of flight
f9Field9Aircraft type, formation count, and wake turbulence
f10Field10Equipment and capability codes
f13Field13Departure aerodrome and time
f15Field15Route: initial speed, level, and route elements
f16Field16Destination, TEET, and alternate aerodromes
f17Option Field17Actual arrival aerodrome and time (present only when status = .completed)
f18Option Field18Other information (equipment details, EET, PBN codes, etc.)

Invariants

The inv field is a conjunction of all cross-field consistency constraints. A value of type Flight is only well-formed when all of the following hold simultaneously:
InvariantConstraint
F8F15LevelIf Field 15 level is absent (VFR), Field 8 rules must be v or z
F8F15RuleIn-route rule changes in Field 15 are consistent with Field 8 initial rules
F9F18TypField 9b designator present ↔ Field 18 TYP absent
F10F18StsRVSM capable (w) and NONRVSM status cannot coexist
F10F18PbnPBN capable (r) ↔ Field 18 PBN non-empty
F10F18Zz in Field 10a ↔ at least one of Field 18 COM/NAV/DAT populated
F13F18DepField 13a departure coding consistent with Field 18 DEP
F15F18DleDelay points in Field 18 DLE are named waypoints in the Field 15 route
F16F18DestField 16a destination coding consistent with Field 18 DEST
F16F18AltnZZZZ entries in Field 16c alternates matched by Field 18 ALTN entries
F16F18EetAll EET durations less than total flight duration (Field 16b)
F16F18DleSum of delay durations less than total flight duration
F16F17DestPlanned destination (Field 16a) differs from actual arrival (Field 17a)
f17 ↔ completedField 17 is present if and only if the flight status is completed
This is a prime illustration of how dependent types in Lean allow data constraints to be packaged directly with the data, giving a precise and machine-verified characterisation of valid flight data.

Type Class Instances for Flight

FlightTime Flight

The flight time period for a Flight is computed from the departure point, departure time, destination, and TEET using adepAdesFlightTime.
instance : FlightTime Flight where
  period flt := adepAdesFlightTime flt.f13.f13a flt.f13.f13b flt.f16.f16a flt.f16.f16b

IsFlight Flight

The FlightId for a Flight is assembled from the aircraft identification, the departure aerodrome, and the computed flight time period.
instance : IsFlight Flight where
  idOf flight := ⟨flight.f7.f7a, flight.f13.f13a, FlightTime.period flight⟩

end FPL

Build docs developers (and LLMs) love