aboutsummaryrefslogtreecommitdiff
path: root/McCarthy.hs
blob: 9f1cb5cfa70b14dbc5262f96fcfc4031e1ab6d3a (plain)
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module McCarthy where

import Prelude hiding ((^), (+), null)

data Sexp = Atom String | Pair Sexp Sexp deriving Show

at = Atom

l []       = at"NIL"
l (x : xs) = Pair x (l xs)

t = l[l[at"AB",at"C"],at"D"]

atom (Atom _ )  = at"T"
atom (Pair _ _) = at"F"

eq (Atom x, Atom y)
    | x == y    = at"T"
    | otherwise = at"F"
eq _ = error "undefined"

car (Pair e1 _) = e1
car _ = error "undefined"

cdr (Pair _ e2) = e2
cdr _ = error "undefined"

cons (e1, e2) = Pair e1 e2

cases ((Atom x, y) : ps)
  | x == "T" = y
  | x == "F" = cases ps
cases _ = error "undefined"

(^) p q = cases[(p, q), (at"T",at"F")]
(+) p q = cases[(p, at"T"), (at"T", q)]
n p = cases[(p, at"F"), (at"T", at"T")]
(-->) p q = cases[(p,q), (at"T",at"T")]

ff(x) = cases[(atom(x), x), (at"T",ff(car(x)))]

subst(x, y, z) = cases
    [ (atom(z), cases[(eq(z, y), x), (at"T", z)])
    , (at"T", cons(subst(x, y, car(z)), subst(x, y, cdr(z))))
    ]

equal(x, y) =
    (atom(x) ^ atom(y) ^ eq(x,y)) +
    (n (atom(x)) ^ n(atom(y)) ^ equal(car(x), car(y)) ^ equal(cdr(x), cdr(y)))

null(x) = atom(x) ^ eq(x, at"NIL")

append(x, y) = cases
    [ (null(x), y)
    , (at"T", cons(car(x), append(cdr(x),y)))
    ]

pair(x, y) = cases
    [ (null(x) ^ null(y), at"NIL")
    , (n(atom(x)) ^ n(atom(y)), cons(l[car(x), car(y)], pair(cdr(x), cdr(y))))
    ]

caar(x)   = car(car(x))
cadar(x)  = car(cdr(car(x)))
cadr(x)   = car(cdr(x))
caddr(x)  = car(cdr(cdr(x)))
caddar(x) = car(cdr(cdr(car(x))))

assoc(x, y) = cases
    [ (eq(caar(y), x), cadar(y))
    , (at"T", assoc(x, cdr(y)))
    ]

sub2(x, z) = cases
    [ (null(x), z)
    , (eq(caar(x), z), cadar(x))
    , (at"T", sub2(cdr(x), z))
    ]

sublis(x, y) = cases
    [ (atom(y), sub2(x, y))
    , (at"T", cons(sublis(x, car(y)),sublis(x, cdr(y))))
    ]

apply(f, args) = eval(cons(f, appq(args)), at"NIL")

appq(m) = cases
    [ (null(m), at"NIL")
    , (at"T", cons(l[at"QUOTE", car(m)], appq(cdr(m))))
    ]

eval(e, a) = cases
    [ (atom(e), assoc(e, a))
    , (atom(car(e)), cases
          [ (eq(car(e), at"QUOTE"), cadr(e))
          , (eq(car(e), at"ATOM"), atom(eval(cadr(e), a)))
          , (eq(car(e), at"EQ"), eq(eval(cadr(e), a), eval(caddr(e), a)))
          , (eq(car(e), at"COND"), evcon(cadr(e), a))
          , (eq(car(e), at"CAR"), car(eval(cadr(e), a)))
          , (eq(car(e), at"CDR"), cdr(eval(cadr(e), a)))
          , (eq(car(e), at"CONS"), cons(eval(cadr(e), a), eval(caddr(e), a)))
          , (at"T", eval(cons(assoc(car(e), a), cdr(e)), a))
          -- , (at"T", eval(cons(assoc(car(e), a), evlis(cdr(e), a)), a))
          ]
      )
    , (eq(caar(e), at"LABEL"), eval(cons(caddar(e), cdr(e)), cons(l[cadar(e), car(e)], a)))
    , (eq(caar(e), at"LAMBDA"), eval(caddar(e), append(pair(cadar(e), evlis(cdr(e), a)), a)))
    ]
  where
    evcon(c, a) = cases[(eval(caar(c), a), eval(cadar(c), a)), (at"T", evcon(cdr(c),a))]
    evlis(m, a) = cases[(null(m), at"NIL"), (at"T", cons(eval(car(m), a), evlis(cdr(m), a)))]