-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCL.hs
More file actions
78 lines (60 loc) · 1.69 KB
/
CL.hs
File metadata and controls
78 lines (60 loc) · 1.69 KB
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
module CL
( Nom, CTm(..), var, cmb
, fvs, mem
, CL(..)
, norm, isNF, red1, redn )
where
import Data.Set (Set, member, empty, singleton, union, delete)
type Nom = String
data CTm c
= Var Nom
| Atm Nom
| Cmb (CTm c) (CTm c)
instance Show (CTm c) where
show ctm = case ctm of
Var nom -> nom
Atm nom -> nom
Cmb opr (Var nom) -> show opr ++ " " ++ nom
Cmb opr (Atm nom) -> show opr ++ " " ++ nom
Cmb opr opd -> show opr ++ " " ++ "(" ++ show opd ++ ")"
var :: Nom -> CTm c
var = Var
cmb :: [CTm c] -> CTm c
cmb = foldl1 Cmb
fvs :: CTm c -> Set Nom
fvs ctm = case ctm of
Var nom -> singleton nom
Atm _ -> empty
Cmb opr opd -> union (fvs opr) (fvs opd)
mem :: Ord a => a -> Set a -> Bool
mem = member
class CL c where
disp :: CTm c -> Either (CTm c -> CTm c) (CTm c)
isnc :: CTm c -> Bool
redc :: CTm c -> Maybe (CTm c)
norm :: CL c => CTm c -> CTm c
norm ctm = case ctm of
Cmb opr opd -> case disp (norm opr) of
Left ctn -> norm (ctn opd)
Right nf -> cmb [nf, norm opd]
_ -> ctm
isNF :: CL c => CTm c -> Bool
isNF ctm = case ctm of
Var _ -> True
Atm _ -> True
_ -> isnc ctm
red1 :: CL c => CTm c -> CTm c
red1 ctm = case redc ctm of
Just stp -> stp
Nothing -> case ctm of
Cmb opr opd | isNF opr -> cmb [opr, red1 opd]
| otherwise -> cmb [red1 opr, opd]
redn :: CL c => Int -> CTm c -> [CTm c]
redn = red []
where red stps n ctm
| isNF ctm = stps
| n == 0 = stps
| otherwise = let stp = red1 ctm
in red (stp : stps)
(if n < 0 then n else n - 1)
stp