4 | module Language.IntrinsicTyping.SECD
6 | import public Data.Late
7 | import Data.List.Elem
8 | import public Data.List.Quantifiers
26 | data Const : Ty -> Type where
27 | AnInt : Int -> Const TyInt
29 | False : Const TyBool
32 | fromInteger : Integer -> Const TyInt
33 | fromInteger n = AnInt (cast n)
48 | FunDump = List (Ty, Ty)
60 | data Step : State -> State -> Type
61 | data Steps : State -> State -> Type
64 | data Step : State -> State -> Type where
68 | LDC : (c : Const ty) -> MkState s e f `Step` MkState (ty :: s) e f
71 | MkState s e f `Step` MkState (ty :: s) e f
73 | LDF : (MkState [] (a :: e) ((a, b) :: f) `Steps` MkState [b] (a :: e) ((a, b) :: f)) ->
74 | MkState s e f `Step` MkState (TyFun a b :: s) e f
76 | LDR : Elem (a,b) f ->
77 | MkState s e f `Step` MkState (TyFun a b :: s) e f
82 | APP : MkState (a :: TyFun a b :: s) e f `Step` MkState (b :: s) e f
84 | TAP : MkState (a :: TyFun a b :: s) e f `Step` MkState (b :: s) e f
86 | RTN : MkState (b :: s) e ((a, b) :: f) `Step` MkState [ b ] e ((a, b) :: f)
91 | BCH : (l, r : MkState s e f `Steps` MkState s' e f) ->
92 | MkState (TyBool :: s) e f `Step` MkState s' e f
97 | FLP : MkState (a :: b :: s) e f `Step` MkState (b :: a :: s) e f
102 | NIL : MkState s e f `Step` MkState (TyList a :: s) e f
104 | CNS : MkState (a :: TyList a :: s) e f `Step` MkState (TyList a :: s) e f
106 | HED : MkState (TyList a :: s) e f `Step` MkState (a :: s) e f
108 | TAL : MkState (TyList a :: s) e f `Step` MkState (TyList a :: s) e f
113 | MKP : MkState (a :: b :: s) e f `Step` MkState (TyPair a b :: s) e f
115 | FST : MkState (TyPair a b :: s) e f `Step` MkState (a :: s) e f
117 | SND : MkState (TyPair a b :: s) e f `Step` MkState (b :: s) e f
122 | ADD : MkState (TyInt :: TyInt :: s) e f `Step` MkState (TyInt :: s) e f
124 | SUB : MkState (TyInt :: TyInt :: s) e f `Step` MkState (TyInt :: s) e f
126 | MUL : MkState (TyInt :: TyInt :: s) e f `Step` MkState (TyInt :: s) e f
131 | EQB : {a : Ty} -> MkState (a :: a :: s) e f `Step` MkState (TyBool :: s) e f
133 | NOT : MkState (TyBool :: s) e f `Step` MkState (TyBool :: s) e f
140 | data Steps : State -> State -> Type where
142 | (::) : Step s t -> Steps t u -> Steps s u
145 | data Stepz : State -> State -> Type where
147 | (:<) : Stepz s t -> Step t u -> Stepz s u
150 | (<>>) : Stepz s t -> Steps t u -> Steps s u
152 | (ss :< s) <>> ts = ss <>> (s :: ts)
155 | (<><) : Stepz s t -> Steps t u -> Stepz s u
157 | ss <>< (t :: ts) = (ss :< t) <>< ts
160 | (++) : Steps s t -> Steps t u -> Steps s u
162 | (s :: ss) ++ ts = s :: (ss ++ ts)
168 | NUL : {a : Ty} -> MkState (TyList a :: s) e f `Steps` MkState (TyBool :: s) e f
172 | LDL : List Int -> MkState s e f `Steps` MkState (TyList TyInt :: s) e f
173 | LDL vs = go [<NIL] ([<] <>< vs) <>> [] where
175 | go : MkState s e f `Stepz` MkState (TyList TyInt :: s) e f ->
177 | MkState s e f `Stepz` MkState (TyList TyInt :: s) e f
179 | go acc (vs :< v) = go (acc :< LDC (AnInt v) :< CNS) vs
181 | FVE : MkState [] [] [] `Steps` MkState [TyInt] [] []
182 | FVE = [LDC 2, LDC 3, ADD]
184 | INC : MkState [] (TyInt :: e) ((TyInt, TyInt) :: f)
185 | `Steps` MkState [TyInt] (TyInt :: e) ((TyInt, TyInt) :: f)
192 | INC2 : MkState [] [] [] `Steps` MkState [TyInt] [] []
199 | THR : MkState [] [] [] `Steps` MkState [TyInt] [] []
201 | [ LDF [ LDF [LDA Here, LDA (There Here), ADD, RTN ], RTN ]
209 | PLS : MkState s e f `Step` MkState (TyFun TyInt (TyFun TyInt TyInt) :: s) e f
210 | PLS = LDF [ LDF [ LDA Here
217 | MAP : {a : Ty} -> MkState [] e f `Step` MkState [ TyFun (TyFun a b) (TyFun (TyList a) (TyList b )) ] e f
218 | MAP = LDF [LDF ( LDA Here
221 | [ LDR Here, LDA Here, TAL, APP
222 | , LDA (There Here), LDA Here, HED, APP
229 | FLD : {a : Ty} -> MkState [] e f `Step`
230 | MkState [TyFun (TyFun b (TyFun a b)) (TyFun b (TyFun (TyList a) b))] e f
231 | FLD = LDF [ LDF [ LDF ( LDA Here
233 | ++ [ BCH [ LDA (There Here) ]
234 | [ LDA (There (There Here))
250 | SUM : MkState [] e f `Steps`
251 | MkState [TyFun (TyList TyInt) TyInt] e f
263 | data Closure : (a, b : Ty) -> Type
268 | Meaning : Ty -> Type
269 | Meaning TyInt = Int
270 | Meaning TyBool = Bool
271 | Meaning (TyPair a b) = (Meaning a, Meaning b)
272 | Meaning (TyList a) = List (Meaning a)
273 | Meaning (TyFun a b) = Closure a b
276 | fromConst : Const ty -> Meaning ty
277 | fromConst (AnInt i) = i
278 | fromConst True = True
279 | fromConst False = False
281 | namespace StackOrEnv
284 | Meaning : List Ty -> Type
285 | Meaning = All Meaning
290 | 0 Meaning : FunDump -> Type
292 | Meaning ((a, b) :: f) = (Closure a b, Meaning f)
295 | tail : {0 f : FunDump} -> Meaning (ab :: f) -> Meaning f
296 | tail {ab = (a, b)} (_, f) = f
299 | lookup : Meaning f -> Elem (a,b) f -> Closure a b
300 | lookup (cl, _) Here = cl
301 | lookup {f = (a, b) :: _} (_, f) (There p) = lookup f p
306 | record Meaning (st : State) where
307 | constructor MkMeaning
308 | stackVal : Meaning st.stack
309 | envVal : Meaning st.env
310 | dumpVal : Meaning st.dump
313 | record Closure (a, b : Ty
) where
314 | constructor MkClosure
316 | {0 localFunDump : FunDump}
317 | code : MkState [] (a :: localEnv) ((a, b) :: localFunDump)
318 | `Steps` MkState [b] (a :: localEnv) ((a, b) :: localFunDump)
319 | envVal : Meaning localEnv
320 | dumpVal : Meaning localFunDump
323 | eqb : (ty : Ty) -> (l, r : Meaning ty) -> Bool
325 | eqbs : (ty : Ty) -> (l, r : Meaning (TyList ty)) -> Bool
327 | eqb TyInt l r = l == r
328 | eqb TyBool l r = l == r
329 | eqb (TyPair a b) (l1, l2) (r1, r2) = eqb a l1 r1 && eqb b l2 r2
330 | eqb (TyList a) l r = eqbs a l r
331 | eqb (TyFun a b) l r = False
333 | eqbs a [] [] = True
334 | eqbs a (l :: ls) (r :: rs) = eqb a l r && eqbs a ls rs
341 | steps : Meaning st -> Steps st st' -> Late (Meaning st')
343 | step : Meaning st -> Step st st' -> Late (Meaning st')
345 | steps st [] = Now st
346 | steps st (stp :: stps)
347 | = do st' <- step st stp
350 | step (MkMeaning s e f) (LDC c) = Now (MkMeaning (fromConst c :: s) e f)
351 | step (MkMeaning s e f) (LDA p) = Now (MkMeaning (indexAll p e :: s) e f)
352 | step (MkMeaning s e f) (LDF cd) = Now (MkMeaning (MkClosure cd e f :: s) e f)
353 | step (MkMeaning s e f) (LDR p) = Now (MkMeaning (lookup f p :: s) e f)
355 | step (MkMeaning (a :: fun :: s) e f) APP
357 | = Later $
do let MkClosure cd e1 f1 = fun
358 | MkMeaning [v] _ _ <- assert_total (steps (MkMeaning [] (a :: e1) (fun, f1)) cd)
359 | Now (MkMeaning (v :: s) e f)
360 | step (MkMeaning (a :: fun :: s) e f) TAP
362 | = Later $
do let MkClosure cd e1 f1 = fun
363 | MkMeaning [v] _ _ <- assert_total (steps (MkMeaning [] (a :: e1) (fun, f1)) cd)
364 | Now (MkMeaning (v :: s) e f)
365 | step (MkMeaning (v :: s) e f) RTN = Now (MkMeaning [v] e f)
367 | step (MkMeaning (b :: s) e f) (BCH l r)
368 | = let st = MkMeaning s e f in
370 | (Later (steps st l))
371 | (Later (steps st r))
373 | step (MkMeaning (a :: b :: s) e f) FLP = Now (MkMeaning (b :: (a :: s)) e f)
375 | step (MkMeaning s e f) NIL = Now (MkMeaning ([] :: s) e f)
376 | step (MkMeaning (x :: xs :: s) e f) CNS = Now (MkMeaning ((x :: xs) :: s) e f)
377 | step (MkMeaning (xs :: s) e f) HED = case xs of
379 | (x :: _) => Now (MkMeaning (x :: s) e f)
380 | step (MkMeaning (xs :: s) e f) TAL = case xs of
382 | (_ :: xs) => Now (MkMeaning (xs :: s) e f)
384 | step (MkMeaning (a :: b :: s) e f) MKP = Now (MkMeaning ((a, b) :: s) e f)
385 | step (MkMeaning (ab :: s) e f) FST = Now (MkMeaning (fst ab :: s) e f)
386 | step (MkMeaning (ab :: s) e f) SND = Now (MkMeaning (snd ab :: s) e f)
388 | step (MkMeaning (m :: n :: s) e f) ADD = Now (MkMeaning (m + n :: s) e f)
389 | step (MkMeaning (m :: n :: s) e f) SUB = Now (MkMeaning (m - n :: s) e f)
390 | step (MkMeaning (m :: n :: s) e f) MUL = Now (MkMeaning (m * n :: s) e f)
392 | step (MkMeaning (x :: y :: s) e f) EQB = Now (MkMeaning (eqb _ x y :: s) e f)
393 | step (MkMeaning (b :: s) e f) NOT = Now (MkMeaning (not b :: s) e f)
396 | run : MkState [] [] [] `Steps` MkState (ty :: _) [] [] -> Nat -> Maybe (Meaning ty)
398 | = do MkMeaning (v :: _) _ _ <- petrol n (steps (MkMeaning [] [] ()) cd)
401 | testFVE : run FVE 0 === Just 5
404 | testINC2 : run INC2 1 === Just 3
407 | testTHR : run THR 2 === Just 3
410 | testLDL : run (LDL [1..4]) 0 === Just [1..4]
413 | testLST : run (SUM ++ LDL [1..4] ++ [APP]) 24 === Just 10
416 | testMAP : run (MAP :: PLS :: LDC 1 :: APP :: APP :: LDL [1..3] ++ [APP]) 13