Spaces:
Sleeping
Sleeping
| -- File: lean/IntervalSpecAeneas.lean | |
| -- Interval Scheduler — Aeneas-compatible specification. | |
| -- Types mirror what Aeneas generates from Vec<(i64,i64)> Rust code. | |
| -- Requires: lake update (fetches the Aeneas package) | |
| import Aeneas | |
| open Aeneas.Primitives | |
| namespace IntervalSpecAeneas | |
| -- Aeneas maps Vec<(i64, i64)> → List (I64 × I64) | |
| abbrev Interval := I64 × I64 | |
| abbrev Intervals := List Interval | |
| -- Insertion sort by start time | |
| private def insertByStart (iv : Interval) : Intervals → Intervals | |
| | [] => [iv] | |
| | x :: rest => | |
| if iv.1.val < x.1.val then iv :: x :: rest | |
| else x :: insertByStart iv rest | |
| private def sortByStart (ivs : Intervals) : Intervals := | |
| ivs.foldl (fun sorted iv => insertByStart iv sorted) [] | |
| -- Remove last element | |
| private def dropLast : Intervals → Intervals | |
| | [] => [] | |
| | [_] => [] | |
| | x :: rest => x :: dropLast rest | |
| -- Merge overlapping/touching intervals (sorted by start) | |
| def mergeIntervals (ivs : Intervals) : Result Intervals := | |
| let sorted := sortByStart ivs | |
| .ok (sorted.foldl (fun acc iv => | |
| match acc.getLast? with | |
| | none => [iv] | |
| | some (ls, le) => | |
| if iv.1.val ≤ le.val | |
| then dropLast acc ++ [(ls, if le.val ≥ iv.2.val then le else iv.2)] | |
| else acc ++ [iv]) []) | |
| -- Insertion sort by end time | |
| private def insertByEnd (iv : Interval) : Intervals → Intervals | |
| | [] => [iv] | |
| | x :: rest => | |
| if iv.2.val < x.2.val then iv :: x :: rest | |
| else x :: insertByEnd iv rest | |
| private def sortByEnd (ivs : Intervals) : Intervals := | |
| ivs.foldl (fun sorted iv => insertByEnd iv sorted) [] | |
| -- Greedy activity selection (sort by end, pick non-overlapping) | |
| def maxSchedule (ivs : Intervals) : Result Intervals := | |
| let sorted := sortByEnd ivs | |
| .ok (sorted.foldl (fun acc iv => | |
| match acc.getLast? with | |
| | none => [iv] | |
| | some (_, le) => | |
| if le.val ≤ iv.1.val then acc ++ [iv] | |
| else acc) []) | |
| -- Helpers for proof | |
| def isSorted : Intervals → Bool | |
| | [] | [_] => true | |
| | (_, a) :: (b, c) :: rest => a.val ≤ b.val && isSorted ((b, c) :: rest) | |
| def noOverlap : Intervals → Bool | |
| | [] | [_] => true | |
| | (_, a) :: (b, c) :: rest => a.val ≤ b.val && noOverlap ((b, c) :: rest) | |
| -- mergeIntervals output is sorted | |
| theorem merge_sorted (ivs : Intervals) : | |
| ∃ r, mergeIntervals ivs = .ok r ∧ isSorted r = true := by | |
| simp only [mergeIntervals] | |
| exact ⟨_, rfl, by sorry⟩ -- Proof mirrors IntervalSpec.merge_sorted | |
| -- mergeIntervals output is non-overlapping | |
| theorem merge_no_overlap (ivs : Intervals) : | |
| ∃ r, mergeIntervals ivs = .ok r ∧ noOverlap r = true := by | |
| simp only [mergeIntervals] | |
| exact ⟨_, rfl, by sorry⟩ -- Proof mirrors IntervalSpec.merge_no_overlap | |
| end IntervalSpecAeneas | |