@@ -85,28 +85,51 @@ wfInd : WellFounded rel => {P : a -> Type} ->
8585 (x : a) -> P x
8686wfInd {rel} step x = accInd step x (wellFounded {rel} x)
8787
88−-- Some basic useful relations
8988
90−||| LT is a well-founded relation on numbers
91−ltAccessible : (n : Nat) -> Accessible LT n
92−ltAccessible n = Access (\v, prf => ltAccessible' {n'=v} n prf)
93− where
94− ltAccessible' : (m : Nat) -> LT n' m -> Accessible LT n'
95− ltAccessible' Z x = absurd x
96− ltAccessible' (S k) (LTESucc x)
97− = Access (\val, p => ltAccessible' k (lteTransitive p x))
98−
99−-- First list is smaller than the second
100−smaller : List a -> List a -> Type
101−smaller xs ys = LT (length xs) (length ys)
102−
103−||| `smaller` is a well-founded relation on lists
104−smallerAcc : (xs : List a) -> Accessible WellFounded.smaller xs
105−smallerAcc xs = Access (\v, prf => smallerAcc' {xs'=v} xs prf)
106− where
107− smallerAcc' : (ys : List a) -> smaller xs' ys -> Accessible smaller xs'
108− smallerAcc' [] x = absurd x
109− smallerAcc' (y :: ys) (LTESucc x)
110− = Access (\val, p => smallerAcc' ys (lteTransitive p x))
89+-- Accessibility for sized types
11190
91+interface Sized a where
92+ size : a -> Nat
11293
94+Smaller : Sized a => a -> a -> Type
95+Smaller x y = size x `LT` size y
96+
97+accessible : Sized a => (x : a) -> Accessible Smaller x
98+accessible x = Access $ f (size x) (ltAccessible $ size x)
99+ where
100+ f : (sizeX : Nat) -> (acc : Accessible LT sizeX)
101+ -> (y : a) -> (size y `LT` sizeX) -> Accessible Smaller y
102+ f Z acc y pf = absurd pf
103+ f (S n) (Access acc) y (LTESucc yLEx)
104+ = Access (\z, zLTy =>
105+ f n (acc n $ LTESucc lteRefl) z (lteTransitive zLTy yLEx)
106+ )
107+
108+ ||| LT is a well-founded relation on numbers
109+ ltAccessible : (n : Nat) -> Accessible LT n
110+ ltAccessible n = Access (\v, prf => ltAccessible' {n'=v} n prf)
111+ where
112+ ltAccessible' : (m : Nat) -> LT n' m -> Accessible LT n'
113+ ltAccessible' Z x = absurd x
114+ ltAccessible' (S k) (LTESucc x)
115+ = Access (\val, p => ltAccessible' k (lteTransitive p x))
116+
117+sizeInd : Sized a
118+ => {P : a -> Type}
119+ -> (step : (x : a) -> ((y : a) -> Smaller y x -> P y) -> P x)
120+ -> (z : a)
121+ -> P z
122+sizeInd step z = accInd step z (accessible z)
123+
124+sizeRec : Sized a
125+ => (step : (x : a) -> ((y : a) -> Smaller y x -> b) -> b)
126+ -> (z : a)
127+ -> b
128+sizeRec step z = accRec step z (accessible z)
129+
130+
131+implementation Sized Nat where
132+ size = \x => x
133+
134+implementation Sized (List a) where
135+ size = length