-
Notifications
You must be signed in to change notification settings - Fork 0
/
Reduction.hs
57 lines (50 loc) · 1.75 KB
/
Reduction.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
module Reduction where
import Terms
import Data.List
-- Reduction
-- There are two reasonable approaches: to separate typechecking from
-- reduction, or to combine them. Combining means only one pass is needed, and
-- the pattern matchings are complete, but modularity is sacrificed. We choose
-- to separate them to better parallel the agda version, and for better
-- extensibility (other operations on welltyped terms can be defined)
-- Right means it's a value
step :: Term -> Either Term Term
step m@(Lam _ _) = Right m
step (App m1 m2) = case step m1 of
Left m1' -> Left (App m1' m2)
Right v1@(Lam _ m) -> case step m2 of
Left m2' -> Left (App v1 m2')
Right m2' -> Left (m2' `substInto` m)
_ -> undefined
step Zero = Right Zero
step (Suc m) = case step m of
Left m' -> Left (Suc m')
Right v -> Right (Suc v)
step (CaseNat m n1 n2) = case step m of
Left m' -> Left (CaseNat m' n1 n2)
Right Zero -> Left n1
Right (Suc v) -> Left (v `substInto` n2)
_ -> undefined
step (Pair m1 m2) = case step m1 of
Left m1' -> Left (Pair m1' m2)
Right v1 -> case step m2 of
Left m2' -> Left (Pair v1 m2')
Right v2 -> Right (Pair v1 v2)
step (CaseProduct m n) = case step m of
Left m' -> Left (CaseProduct m' n)
Right (Pair v1 v2) -> Left (v2 `substInto` (v1 `substInto` n))
_ -> undefined
step m@(Mu m') = Left (m `substInto` m')
step _ = undefined
steps :: Term -> [Term]
steps m = case step m of
Left m' -> m' : steps m'
Right v -> [v]
unquoteNat :: Term -> Word
unquoteNat Zero = 0
unquoteNat (Suc m) = 1 + unquoteNat m
unquoteNat _ = undefined
-- Examples of evaluations
main :: IO ()
main = mapM_ putStrLn $ intersperse "—→" $
map (prettyPrintTerm 2) (steps (App (App plus' two') two'))