19 | module Control.WellFounded
21 | import Control.Relation
28 | data Accessible : (rel : a -> a -> Type) -> (x : a) -> Type where
29 | Access : (rec : (y : a) -> rel y x -> Accessible rel y) ->
34 | interface WellFounded a rel where
35 | wellFounded : (x : a) -> Accessible rel x
44 | accRec : {0 rel : (arg1 : a) -> (arg2 : a) -> Type} ->
45 | (step : (x : a) -> ((y : a) -> rel y x -> b) -> b) ->
46 | (z : a) -> (0 acc : Accessible rel z) -> b
47 | accRec step z (Access f) =
48 | step z $
\yarg, lt => accRec step yarg (f yarg lt)
55 | accInd : {0 rel : a -> a -> Type} -> {0 P : a -> Type} ->
56 | (step : (x : a) -> ((y : a) -> rel y x -> P y) -> P x) ->
57 | (z : a) -> (0 acc : Accessible rel z) -> P z
58 | accInd step z (Access f) =
59 | step z $
\y, lt => accInd step y (f y lt)
63 | accIndProp : {0 P : a -> Type} ->
64 | (step : (x : a) -> ((y : a) -> rel y x -> P y) -> P x) ->
65 | {0 RP : (x : a) -> P x -> Type} ->
67 | (f : (y : a) -> rel y x -> P y) ->
68 | ((y : a) -> (isRel : rel y x) -> RP y (f y isRel)) ->
70 | (z : a) -> (0 acc : Accessible rel z) -> RP z (accInd step z acc)
71 | accIndProp step ih z (Access rec) =
72 | ih z (\y, lt => accInd step y (rec y lt))
73 | (\y, lt => accIndProp {RP} step ih y (rec y lt))
80 | wfRec : (0 _ : WellFounded a rel) =>
81 | (step : (x : a) -> ((y : a) -> rel y x -> b) -> b) ->
83 | wfRec step x = accRec step x (wellFounded {rel} x)
90 | wfInd : (0 _ : WellFounded a rel) => {0 P : a -> Type} ->
91 | (step : (x : a) -> ((y : a) -> rel y x -> P y) -> P x) ->
93 | wfInd step myz = accInd step myz (wellFounded {rel} myz)
97 | wfIndProp : (0 _ : WellFounded a rel) =>
98 | {0 P : a -> Type} ->
99 | (step : (x : a) -> ((y : a) -> rel y x -> P y) -> P x) ->
100 | {0 RP : (x : a) -> P x -> Type} ->
102 | (f : (y : a) -> rel y x -> P y) ->
103 | ((y : a) -> (isRel : rel y x) -> RP y (f y isRel)) ->
104 | RP x (step x f)) ->
105 | (myz : a) -> RP myz (wfInd step myz)
106 | wfIndProp step ih myz = accIndProp {RP} step ih myz (wellFounded {rel} myz)
110 | interface Sized a where
111 | constructor MkSized
112 | total size : a -> Nat
116 | Smaller : Sized a => a -> a -> Type
117 | Smaller = \x, y => size x `LT` size y
121 | SizeAccessible : Sized a => a -> Type
122 | SizeAccessible = Accessible Smaller
126 | sizeAccessible : Sized a => (x : a) -> SizeAccessible x
127 | sizeAccessible x = Access (acc $
size x)
129 | acc : (sizeX : Nat) -> (y : a) -> (size y `LT` sizeX) -> SizeAccessible y
130 | acc (S x') y (LTESucc yLEx')
131 | = Access $
\z, zLTy => acc x' z $
transitive zLTy yLEx'
137 | sizeInd : Sized a => {0 P : a -> Type} ->
138 | (step : (x : a) -> ((y : a) -> Smaller y x -> P y) -> P x) ->
141 | sizeInd step z = accInd step z (sizeAccessible z)
147 | sizeRec : Sized a =>
148 | (step : (x : a) -> ((y : a) -> Smaller y x -> b) -> b) ->
150 | sizeRec step z = accRec step z (sizeAccessible z)
157 | WellFounded Nat LT where
158 | wellFounded = sizeAccessible
161 | Sized (List a) where
165 | (Sized a, Sized b) => Sized (Pair a b) where
166 | size (x,y) = size x + size y