PageRenderTime 67ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/exercise2/exercise2.lhs

http://sauce-code.googlecode.com/
Haskell | 1922 lines | 1571 code | 186 blank | 165 comment | 95 complexity | 72f37ed1c3f238f3c98603a4efa9431b MD5 | raw file
  1. %% Literate Haskell script intended for lhs2TeX.
  2. \documentclass[10pt]{article}
  3. %include polycode.fmt
  4. %format union = "\cup"
  5. %format `union` = "\cup"
  6. %format Hole = "\square"
  7. %format MachineTerminate ="\varodot"
  8. %format CEKMachineTerminate ="\varodot"
  9. %format alpha = "\alpha"
  10. %format gamma = "\gamma"
  11. %format zeta = "\zeta"
  12. %format kappa = "\kappa"
  13. %format kappa'
  14. %format capGamma = "\Gamma"
  15. %format sigma = "\sigma"
  16. %format tau = "\tau"
  17. %format taus = "\tau s"
  18. %format ltaus = "l\tau s"
  19. %format tau1
  20. %format tau1'
  21. %format tau2
  22. %format tau11
  23. %format tau12
  24. %format upsilon = "\upsilon"
  25. %format xi = "\xi"
  26. %format t12
  27. %format t1
  28. %format t1'
  29. %format t2
  30. %format t2'
  31. %format t3
  32. %format nv1
  33. \usepackage{fullpage}
  34. \usepackage{mathpazo}
  35. \usepackage{verbatim}
  36. \usepackage{graphicx}
  37. \usepackage{color}
  38. \usepackage[centertags]{amsmath}
  39. \usepackage{amsfonts}
  40. \usepackage{amssymb}
  41. \usepackage{mathrsfs}
  42. \usepackage{amsthm}
  43. \usepackage{stmaryrd}
  44. \usepackage{soul}
  45. \usepackage{url}
  46. \usepackage{vmargin}
  47. \setpapersize{USletter}
  48. \setmarginsrb{1.1in}{1.0in}{1.1in}{0.6in}{0.3in}{0.3in}{0.0in}{0.2in}
  49. \parindent 0in \setlength{\parindent}{0in} \setlength{\parskip}{1ex}
  50. \usepackage{epsfig}
  51. \usepackage{rotating}
  52. \usepackage{mathpazo,amsmath,amssymb}
  53. \title{Exercise 2, CS 555}
  54. \author{\textbf{By:} Sauce Code Team (Dandan Mo, Qi Lu, Yiming Yang)}
  55. \date{\textbf{Due:} March 21st, 2012}
  56. \begin{document}
  57. \maketitle
  58. \thispagestyle{empty}
  59. \newpage
  60. \section{Enriching the Core Lambda Language}
  61. \subsection{Lexer and Parser}
  62. 1): We add ``LET",``IN",``END",``FIX" to the Token and add corresponding show Token functions
  63. \begin{code}
  64. data Token = ARROW
  65. | LPAR
  66. | COMMA
  67. | RPAR
  68. | BOOL
  69. | INT
  70. | ABS
  71. | COLON
  72. | FULLSTOP
  73. | APP
  74. | TRUE
  75. | FALSE
  76. | IF
  77. | THEN
  78. | ELSE
  79. | FI
  80. | PLUS
  81. | SUB
  82. | MUL
  83. | DIV
  84. | NAND
  85. | EQUAL
  86. | LT_keyword
  87. | ID String
  88. | NUM String
  89. | LET
  90. | IN
  91. | END
  92. | FIX
  93. deriving Eq
  94. instance Show Token where
  95. show ARROW = "->"
  96. show LPAR = "("
  97. show COMMA = ","
  98. show RPAR = ")"
  99. show BOOL = "Bool"
  100. show INT = "Int"
  101. show ABS = "abs"
  102. show COLON = ":"
  103. show FULLSTOP = "."
  104. show APP = "app"
  105. show TRUE = "true"
  106. show FALSE = "false"
  107. show IF = "if"
  108. show THEN = "then"
  109. show ELSE = "else"
  110. show FI = "fi"
  111. show PLUS = "+"
  112. show SUB = "-"
  113. show MUL = "*"
  114. show DIV = "/"
  115. show NAND = "^"
  116. show EQUAL = "="
  117. show LT_keyword = "<"
  118. show (ID id) = id
  119. show (NUM num) = num
  120. show (LET) = "let"
  121. show (IN) = "in"
  122. show (END) = "end"
  123. show (FIX) = "fix"
  124. \end{code}
  125. For the Token identifier and decimal number, we use regular expression to recognize them, so we have two corresponding subscan function to deal with them. When we get a identifier, we check if it belongs to the keywords, if so we get the corresponding token, otherwise we get an id.\\
  126. \begin{code}
  127. --reguar expression
  128. ex_num = mkRegex "(0|[1-9][0-9]*)"
  129. ex_id = mkRegex "([a-zA-Z][a-zA-Z0-9_]*)"
  130. --subscan for id and keywords
  131. subscan1 :: String -> Maybe ([Token],String)
  132. subscan1 str = case (matchRegexAll ex_id str) of
  133. Just (a1,a2,a3,a4) -> case a1 of
  134. "" -> case a2 of
  135. "Bool" -> Just ([BOOL],a3)
  136. "Int" -> Just ([INT],a3)
  137. "abs" -> Just ([ABS],a3)
  138. "app" -> Just ([APP],a3)
  139. "true" -> Just ([TRUE],a3)
  140. "false" -> Just ([FALSE],a3)
  141. "if" -> Just ([IF],a3)
  142. "then" -> Just ([THEN],a3)
  143. "else" -> Just ([ELSE],a3)
  144. "fix" -> Just ([FIX],a3)
  145. "fi" -> Just ([FI],a3)
  146. "let" -> Just ([LET],a3)
  147. "in" -> Just ([IN],a3)
  148. "end" -> Just ([END],a3)
  149. _ -> Just ([ID a2],a3)
  150. _ -> Nothing
  151. Nothing -> Nothing
  152. --subscan for num
  153. subscan2 :: String -> Maybe ([Token],String)
  154. subscan2 str = case (matchRegexAll ex_num str) of
  155. Just (a1,a2,a3,a4) -> case a1 of
  156. "" -> Just ([NUM a2],a3)
  157. _ -> Nothing
  158. Nothing -> Nothing
  159. \end{code}
  160. Function scan takes an input string and returns a list tokens. If unexpected symbols exists,or the input string cannot mactch any defined token, the function reports errors and the program stops at the lexer level.\\
  161. \begin{code}
  162. --lexer
  163. scan :: String -> [Token]
  164. scan "" = []
  165. --white spase
  166. scan (' ':xs) = scan xs
  167. scan ('\t':xs) = scan xs
  168. scan ('\n':xs) = scan xs
  169. --symbol
  170. scan (':':xs) = [COLON] ++ scan xs
  171. scan ('-':'>':xs) = [ARROW] ++ scan xs
  172. scan ('(':xs) = [LPAR] ++ scan xs
  173. scan (',':xs) = [COMMA] ++ scan xs
  174. scan (')':xs) = [RPAR] ++ scan xs
  175. scan ('.':xs) = [FULLSTOP] ++ scan xs
  176. --special operator
  177. scan ('+':xs) = [PLUS] ++ scan xs
  178. scan ('-':xs) = [SUB] ++ scan xs
  179. scan ('*':xs) = [MUL] ++ scan xs
  180. scan ('/':xs) = [DIV] ++ scan xs
  181. scan ('^':xs) = [NAND] ++ scan xs
  182. scan ('=':xs) = [EQUAL] ++ scan xs
  183. scan ('<':xs) = [LT_keyword] ++ scan xs
  184. --id,keywords and num
  185. scan str = case subscan1 str of
  186. Nothing -> case subscan2 str of
  187. Nothing -> error "[Scan]err: unexpected symbols!"
  188. Just (tok,xs) -> tok ++ scan xs
  189. Just (tok,xs) -> tok ++ scan xs
  190. str str = error "[Scan]err: unexpected symbols!"
  191. \end{code}
  192. 2):Parser takes a list of tokens, returns a term. We define the two data structures Type and Term, and two functions parseType and parseTerm to deal with them.\\
  193. parseType function returns a matched Type and the remaining tokens, parseTerm function returns a matched Term and the remaining tokens.\\
  194. We add Term ``Let Var Term Term" and ``Fix Term" and their related show functions.\\
  195. Data structure:\\
  196. \begin{code}
  197. data Type = TypeArrow Type Type
  198. | TypeBool
  199. | TypeInt
  200. deriving Eq
  201. instance Show Type where
  202. show (TypeArrow tau1 tau2) = "->(" ++ show tau1 ++ "," ++ show tau2 ++ ")"
  203. show TypeBool = "Bool"
  204. show TypeInt = "Int"
  205. type Var = String
  206. data Term = Var Var
  207. | Abs Var Type Term
  208. | App Term Term
  209. | Tru
  210. | Fls
  211. | If Term Term Term
  212. | IntConst Integer
  213. | IntAdd Term Term
  214. | IntSub Term Term
  215. | IntMul Term Term
  216. | IntDiv Term Term
  217. | IntNand Term Term
  218. | IntEq Term Term
  219. | IntLt Term Term
  220. | Fix Term
  221. | Let Var Term Term
  222. deriving Eq
  223. instance Show Term where
  224. show (Var x) = x
  225. show (Abs x tau t) = "abs(" ++ x ++ ":" ++ show tau ++ "." ++ show t ++ ")"
  226. show (App t1 t2) = "app(" ++ show t1 ++ "," ++ show t2 ++ ")"
  227. show Tru = "true"
  228. show Fls = "false"
  229. show (If t1 t2 t3) = "if " ++ show t1 ++ " then " ++ show t2 ++ " else " ++ show t3 ++ " fi"
  230. show (IntConst n) = show n
  231. show (IntAdd t1 t2) = "+(" ++ show t1 ++ "," ++ show t2 ++ ")"
  232. show (IntSub t1 t2) = "-(" ++ show t1 ++ "," ++ show t2 ++ ")"
  233. show (IntMul t1 t2) = "*(" ++ show t1 ++ "," ++ show t2 ++ ")"
  234. show (IntDiv t1 t2) = "/(" ++ show t1 ++ "," ++ show t2 ++ ")"
  235. show (IntNand t1 t2) = "^(" ++ show t1 ++ "," ++ show t2 ++ ")"
  236. show (IntEq t1 t2) = "=(" ++ show t1 ++ "," ++ show t2 ++ ")"
  237. show (IntLt t1 t2) = "<(" ++ show t1 ++ "," ++ show t2 ++ ")"
  238. show (Fix t) = "fix " ++ show t
  239. show (Let v t1 t2) = "let " ++ v ++ "=" ++ show t1 ++ "in" ++ show t2
  240. \end{code}
  241. Function parseType, parseTerm and parse:\\
  242. In parseTerm, we add new pattern for let-in-end expression and fix-expression.\\
  243. \begin{code}
  244. --parser
  245. --type parser
  246. parseType :: [Token] -> Maybe (Type,[Token])
  247. parseType (BOOL:ty) = Just (TypeBool,ty)
  248. parseType (INT:ty) = Just (TypeInt,ty)
  249. parseType (RPAR:ty) = parseType ty
  250. parseType (COMMA:ty) = parseType ty
  251. parseType (ARROW:LPAR:ty) =
  252. case parseType ty of
  253. Just (t1,(COMMA:tl)) -> case parseType tl of
  254. Just (t2,(RPAR:tll)) -> Just ((TypeArrow t1 t2),tll)
  255. Nothing -> Nothing
  256. Nothing -> Nothing
  257. parseType tok = error "[P]err: type parsing error!"
  258. --term parser
  259. parseTerm :: [Token] -> Maybe (Term,[Token])
  260. ----id
  261. parseTerm ((ID id):ts) = Just ((Var id),ts)
  262. ----num
  263. parseTerm ((NUM num):ts) = Just ((IntConst (read num::Integer)),ts)
  264. ----symbol
  265. --parseTerm (COMMA:ts) = parseTerm ts
  266. --parseTerm (COLON:ts) = parseTerm ts
  267. --parseTerm (RPAR:ts) = parseTerm ts
  268. --parseTerm (FULLSTOP:ts) = parseTerm ts
  269. ----keyword
  270. parseTerm (THEN:ts) = parseTerm ts
  271. parseTerm (ELSE:ts) = parseTerm ts
  272. parseTerm (FI:ts) = parseTerm ts
  273. parseTerm (TRUE:ts) = Just (Tru,ts)
  274. parseTerm (FALSE:ts) = Just (Fls,ts)
  275. ----(term)
  276. parseTerm (LPAR:ts) = case parseTerm ts of
  277. Just (t,(RPAR:tl)) -> Just (t,tl)
  278. Nothing -> Nothing
  279. _ -> error "[P]err: t is not a term in the (t)"
  280. ----op
  281. parseTerm (PLUS:LPAR:ts) =
  282. case parseTerm ts of
  283. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  284. Just (t2,(RPAR:tll)) -> Just ((IntAdd t1 t2),tll)
  285. Nothing -> Nothing
  286. _ -> error "[P]err: plus term"
  287. Nothing -> Nothing
  288. _ -> error "[P]err: plus term"
  289. parseTerm (SUB:LPAR:ts) =
  290. case parseTerm ts of
  291. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  292. Just (t2,(RPAR:tll)) -> Just ((IntSub t1 t2),tll)
  293. Nothing -> Nothing
  294. _ -> error "[P]err: sub term"
  295. Nothing -> Nothing
  296. _ -> error "[P]err: sub term"
  297. parseTerm (MUL:LPAR:ts) =
  298. case parseTerm ts of
  299. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  300. Just (t2,(RPAR:tll)) -> Just ((IntMul t1 t2),tll)
  301. Nothing -> Nothing
  302. _ -> error "[P]err: mul term"
  303. Nothing -> Nothing
  304. _ -> error "[P]err: mul term"
  305. parseTerm (DIV:LPAR:ts) =
  306. case parseTerm ts of
  307. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  308. Just (t2,(RPAR:tll)) -> Just ((IntDiv t1 t2),tll)
  309. Nothing -> Nothing
  310. _ -> error "[P]err: div term"
  311. Nothing -> Nothing
  312. _ -> error "[P]err: div term"
  313. parseTerm (NAND:LPAR:ts) =
  314. case parseTerm ts of
  315. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  316. Just (t2,(RPAR:tll)) -> Just ((IntNand t1 t2),tll)
  317. Nothing -> Nothing
  318. _ -> error "[P]err: nand term"
  319. Nothing -> Nothing
  320. _ -> error "[P]err: nand term"
  321. parseTerm (EQUAL:LPAR:ts) =
  322. case parseTerm ts of
  323. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  324. Just (t2,(RPAR:tll)) -> Just ((IntEq t1 t2),tll)
  325. Nothing -> Nothing
  326. _ -> error "[P]err: eq term"
  327. Nothing -> Nothing
  328. _ -> error "[P]err: eq term"
  329. parseTerm (LT_keyword:LPAR:ts) =
  330. case parseTerm ts of
  331. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  332. Just (t2,(RPAR:tll)) -> Just ((IntLt t1 t2),tll)
  333. Nothing -> Nothing
  334. _ -> error "[P]err: lt term"
  335. Nothing -> Nothing
  336. _ -> error "[P]err: lt term"
  337. ----if-then-else
  338. parseTerm (IF:ts) =
  339. case parseTerm ts of
  340. Just (t1,(THEN:tl)) -> case parseTerm tl of
  341. Just (t2,(ELSE:tll)) -> case parseTerm tll of
  342. Just (t3,(FI:tn)) -> Just((If t1 t2 t3),tn)
  343. Nothing -> Nothing
  344. _ -> error "[P]err: if term"
  345. Nothing -> Nothing
  346. _ -> error "[P]err: if term"
  347. Nothing -> Nothing
  348. _ -> error "[P]err: if term"
  349. ----fix
  350. parseTerm (FIX:LPAR:ts) = case parseTerm ts of
  351. Just (t1,(RPAR:tl)) -> Just ((Fix t1),tl)
  352. Nothing -> Nothing
  353. _ -> error "[P]err: fix term"
  354. ----abs
  355. parseTerm (ABS:LPAR:(ID id):COLON:ts) =
  356. case parseType ts of
  357. Just (ty,(FULLSTOP:tl)) -> case parseTerm tl of
  358. Just (t,(RPAR:tll)) -> Just ((Abs id ty t),tll)
  359. Nothing -> Nothing
  360. _ -> error "[P]err: abs term"
  361. Nothing -> Nothing
  362. _ -> error "[P]err: abs term"
  363. ----app
  364. parseTerm (APP:LPAR:ts) = case parseTerm ts of
  365. Just (t1,(COMMA:tl)) -> case parseTerm tl of
  366. Just (t2,(RPAR:tll)) -> Just ((App t1 t2),tll)
  367. Nothing -> Nothing
  368. _ -> error "[P]err: app term"
  369. Nothing -> Nothing
  370. _ -> error "[P]err: app term"
  371. ----let-in-end
  372. parseTerm (LET:(ID id):EQUAL:ts) = case parseTerm ts of
  373. Just (t1,(IN:tl)) -> case parseTerm tl of
  374. Just (t2,(END:tll)) -> Just ((Let id t1 t2),tll)
  375. Nothing -> Nothing
  376. _ -> error "[P]err: let term"
  377. Nothing -> Nothing
  378. _ -> error "[P]err: let term"
  379. ----otherwise
  380. parseTerm tok = Nothing
  381. --parser
  382. parse :: [Token] -> Term
  383. parse t =
  384. case parseTerm t of
  385. Just (x,t) -> case t of
  386. [] -> x
  387. _ -> error "parsing error!"
  388. Nothing -> error "parsing error!"
  389. \end{code}
  390. If the input string can't match any defined Term, function parser reports an error and the program stops at the parser level.\\
  391. \subsection{Auxiliary Functions}
  392. \paragraph{}
  393. The implementation of the auxiliary functions are in the AbstractSyntax module.
  394. \ \\
  395. \begin{code}
  396. -- list of free variables of a term
  397. fv :: Term -> [Var]
  398. fv (Var x) = [x]
  399. fv (Abs x _ t) = filter (/=x) (fv t)
  400. fv (App t1 t2) = (fv t1) ++ (fv t2)
  401. fv (If t1 t2 t3) = (fv t1) ++ (fv t2) ++ (fv t3)
  402. fv (IntAdd t1 t2) = (fv t1) ++ (fv t2)
  403. fv (IntSub t1 t2) = (fv t1) ++ (fv t2)
  404. fv (IntMul t1 t2) = (fv t1) ++ (fv t2)
  405. fv (IntDiv t1 t2) = (fv t1) ++ (fv t2)
  406. fv (IntNand t1 t2) = (fv t1) ++ (fv t2)
  407. fv (IntEq t1 t2) = (fv t1) ++ (fv t2)
  408. fv (IntLt t1 t2) = (fv t1) ++ (fv t2)
  409. fv (Fix t) = fv t
  410. fv (Let x t1 t2) = (fv t1) ++ (filter (/=x) (fv t2))
  411. fv _ = []
  412. subst :: Var -> Term -> Term -> Term
  413. subst x s (Var v) = if x == v then s else (Var v)
  414. subst x s (Abs y tau t1) =
  415. if x == y then
  416. Abs y tau t1
  417. else
  418. Abs y tau (subst x s t1)
  419. subst x s (App t1 t2) = App (subst x s t1) (subst x s t2)
  420. subst x s (If t1 t2 t3) = If (subst x s t1) (subst x s t2) (subst x s t3)
  421. subst x s (IntAdd t1 t2) = IntAdd (subst x s t1) (subst x s t2)
  422. subst x s (IntSub t1 t2) = IntSub (subst x s t1) (subst x s t2)
  423. subst x s (IntMul t1 t2) = IntMul (subst x s t1) (subst x s t2)
  424. subst x s (IntDiv t1 t2) = IntDiv (subst x s t1) (subst x s t2)
  425. subst x s (IntNand t1 t2) = IntNand (subst x s t1) (subst x s t2)
  426. subst x s (IntEq t1 t2) = IntEq (subst x s t1) (subst x s t2)
  427. subst x s (IntLt t1 t2) = IntLt (subst x s t1) (subst x s t2)
  428. subst x s (Fix t) = Fix (subst x s t)
  429. subst x s (Let y t1 t2) = Let y (subst x s t1) (subst x s t2)
  430. subst x s t = t
  431. isValue :: Term -> Bool
  432. isValue (Abs _ _ _) = True
  433. isValue Tru = True
  434. isValue Fls = True
  435. isValue (IntConst _) = True
  436. isValue _ = False
  437. \end{code}
  438. \ \\
  439. \subsection{Arithmetic}
  440. \begin{code}
  441. module IntegerArithmetic where
  442. import Data.Bits
  443. intRestrictRangeAddMul :: Integer -> Integer
  444. intRestrictRangeAddMul m = m `mod` 4294967296
  445. intAdd :: Integer -> Integer -> Integer
  446. intAdd m n = intRestrictRangeAddMul (m + n)
  447. intSub :: Integer -> Integer -> Integer
  448. intSub m n = m - n
  449. intMul :: Integer -> Integer -> Integer
  450. intMul m n = intRestrictRangeAddMul (m * n)
  451. intDiv :: Integer -> Integer -> Integer
  452. intDiv m n = if n == 0 then error "integer division by zero" else m `div` n
  453. intNand :: Integer -> Integer -> Integer
  454. intNand m n = complement (m .&. n)
  455. intEq :: Integer -> Integer -> Bool
  456. intEq m n = m == n
  457. intLt :: Integer -> Integer -> Bool
  458. intLt m n = m < n
  459. \end{code}
  460. \subsection{Structural Operational Semantics}
  461. \subsubsection{Formal Rules}
  462. \paragraph{}
  463. Formally stating the rules that give the structural operational semantics of the core lambda language, the rules are listed below:
  464. \[
  465. \text{if true then } t_2 \text{ else } t_3 \rightarrow t_2 \text{\quad (\textsc{E-IfTrue})}
  466. \]
  467. \ \\
  468. \[
  469. \text{if false then } t_2 \text{ else } t_3 \rightarrow t_3 \text{(\quad \textsc{E-IfFalse})}
  470. \]
  471. \ \\
  472. \[
  473. \frac{t_1 \rightarrow t'_1}{\text{if } t_1 \text{ then } t_2 \text{ else } t_3 \rightarrow \text{if } t'_1 \text{ then } t_2 \text{ else} t_3} \text{\quad (\textsc{E-If})}
  474. \]
  475. \ \\
  476. \[
  477. \frac{t_1 \rightarrow t'_1}{t_1 \text{\ } t_2 \rightarrow t'_1 \text{\ } t_2}\text{\quad {\textsc{E-App1}}}
  478. \]
  479. \ \\
  480. \[
  481. \frac{t_2 \rightarrow t'_2}{t_1 \text{\ } t_2 \rightarrow t_1 \text{\ } t'_2}\text{\quad {\textsc{E-App2}}}
  482. \]
  483. \ \\
  484. \[
  485. (\lambda x: T_{11}.t_{12})v_2 \rightarrow [ x \mapsto v_2 ] _{12} \text{\quad (\textsc{E-AppAbs})}
  486. \]
  487. \ \\
  488. \[
  489. \frac{t_1 \rightarrow t'_1}{+(t_1, t_2) \rightarrow +(t'_1, t_2)} \text{\quad (\textsc{E-IntAdd1})}
  490. \]
  491. \ \\
  492. \[
  493. \frac{t_2 \rightarrow t'_2}{+(t_1, t_2) \rightarrow +(t_1, t'_2)} \text{\quad (\textsc{E-IntAdd2})}
  494. \]
  495. \ \\
  496. \[
  497. +(v_1, v_2) \rightarrow v_1 \widetilde{+} v_2 \text{\quad (\textsc{E-IntAppAdd})}
  498. \]
  499. \ \\
  500. \[
  501. \frac{t_1 \rightarrow t'_1}{\-(t_1, t_2) \rightarrow -(t'_1, t_2)} \text{\quad (\textsc{E-IntSub1})}
  502. \]
  503. \ \\
  504. \[
  505. \frac{t_2 \rightarrow t'_2}{\-(t_1, t_2) \rightarrow -(t_1, t'_2)} \text{\quad (\textsc{E-IntSub2})}
  506. \]
  507. \ \\
  508. \[
  509. -(v_1, v_2) \rightarrow v_1 \widetilde{-} v_2 \text{\quad (\textsc{E-AppIntSub})}
  510. \]
  511. \ \\
  512. \[
  513. \frac{t_1 \rightarrow t'_1}{*(t_1, t_2) \rightarrow *(t'_1, t_2)} \text{\quad (\textsc{E-IntMul1})}
  514. \]
  515. \ \\
  516. \[
  517. \frac{t_2 \rightarrow t'_2}{*(t_1, t_2) \rightarrow *(t_1, t'_2)} \text{\quad (\textsc{E-IntMul2})}
  518. \]
  519. \ \\
  520. \[
  521. *(v_1, v_2) \rightarrow v_1 \widetilde{*} v_2 \text{\quad (\textsc{E-AppIntMul})}
  522. \]
  523. \ \\
  524. \[
  525. \frac{t_1 \rightarrow t'_1}{/(t_1, t_2) \rightarrow /(t'_1, t_2)} \text{\quad (\textsc{E-IntDiv1})}
  526. \]
  527. \ \\
  528. \[
  529. \frac{t_2 \rightarrow t'_2}{/(t_1, t_2) \rightarrow /(t_1, t'_2)} \text{\quad (\textsc{E-IntDiv2})}
  530. \]
  531. \ \\
  532. \[
  533. /(v_1, v_2) \rightarrow v_1 \widetilde{/} v_2 \text{\quad (\textsc{E-AppIntDiv})}
  534. \]
  535. \ \\
  536. \[
  537. \frac{t_1 \rightarrow t'_1}{\wedge(t_1, t_2) \rightarrow \wedge(t'_1, t_2)} \text{\quad (\textsc{E-IntNand1})}
  538. \]
  539. \ \\
  540. \[
  541. \frac{t_2 \rightarrow t'_2}{\wedge(t_1, t_2) \rightarrow \wedge(t_1, t'_2)} \text{\quad (\textsc{E-IntNand2})}
  542. \]
  543. \ \\
  544. \[
  545. \wedge(v_1, v_2) \rightarrow v_1 \widetilde{\wedge} v_2 \text{\quad (\textsc{E-AppIntNand})}
  546. \]
  547. \ \\
  548. \[
  549. \frac{t_1 \rightarrow t'_1}{=(t_1, t_2) \rightarrow =(t'_1, t_2)} \text{\quad (\textsc{E-IntEq1})}
  550. \]
  551. \ \\
  552. \[
  553. \frac{t_2 \rightarrow t'_2}{=(t_1, t_2) \rightarrow =(t_1, t'_2)} \text{\quad (\textsc{E-IntEq2})}
  554. \]
  555. \ \\
  556. \[
  557. =(v_1, v_2) \rightarrow v_1 \widetilde{\equiv} v_2 \text{\quad (\textsc{E-AppIntEq})}
  558. \]
  559. \ \\
  560. \[
  561. \frac{t_1 \rightarrow t'_1}{<(t_1, t_2) \rightarrow <(t'_1, t_2)} \text{\quad (\textsc{E-IntLt1})}
  562. \]
  563. \ \\
  564. \[
  565. \frac{t_2 \rightarrow t'_2}{<(t_1, t_2) \rightarrow <(t_1, t'_2)} \text{\quad (\textsc{E-IntLt2})}
  566. \]
  567. \ \\
  568. \[
  569. <(v_1, v_2) \rightarrow v_1 \widetilde{<} v_2 \text{\quad (\textsc{E-AppIntLt})}
  570. \]
  571. \ \\
  572. where
  573. \begin{align*}
  574. \widetilde{+} &\text{\quad \quad is the funtion that adds the two arguments and returns an Integer result}\\
  575. \widetilde{-} &\text{\quad \quad is the function that subtracts the two arguments and returns an Integer result}\\
  576. \widetilde{*} &\text{\quad \quad is the function that times the two arguments and returns an Integer result}\\
  577. \widetilde{/} &\text{\quad \quad is the function that divides the two arguments and returns an Integer result}\\
  578. \widetilde{\wedge} &\text{\quad \quad is the function that gets the nand result of the two arguments and returns it }\\
  579. \widetilde{\equiv} &\text{\quad \quad is the function that judges whether the two values are equal. If so, returns \textbf{true}, otherwise \textbf{false}}\\
  580. \widetilde{<} &\text{\quad \quad is the function that judges whether the first value is less than the second one.} \\
  581. &\text{\quad \quad \ If so, returns \textbf{true}, otherwise \textbf{false}}
  582. \end{align*}
  583. \[
  584. \text{fix }(\lambda x:T_1.\text{\ }t_2) \rightarrow [x\mapsto \text{fix } (\lambda x:T_1.\text{\ }t_2)]t_2 \text{\quad (\textsc{E-FixBeta})}
  585. \]
  586. \[
  587. \frac{t_1 \rightarrow t'_1}{\text{fix }t_1 \rightarrow \text{fix } t'_1} \text{\quad (\textsc{E-Fix})}
  588. \]
  589. \[
  590. \text{let } x=v_1 \text{ in } t_2 \rightarrow [x\mapsto v_1] t_2 \text{\quad (\textsc{E-LetV})}
  591. \]
  592. \[
  593. \frac{t_1 \rightarrow t'_1}{\text{let } x=t_1 \text{ in } t_2 \rightarrow \text{let } x=t'_1 \text{ in } t_2} \text{\quad (\textsc{E-Let})}
  594. \]
  595. \subsubsection{Haskell Implementation}
  596. \begin{code}
  597. module StructuralOperationalSemantics where
  598. import List
  599. import qualified AbstractSyntax as S
  600. import qualified IntegerArithmetic as I
  601. eval1 :: S.Term -> Maybe S.Term
  602. -- E-IFTRUE
  603. eval1 (S.If S.Tru t2 t3) = Just t2
  604. -- E-IFFALSE
  605. eval1 (S.If S.Fls t2 t3) = Just t3
  606. -- E-IF
  607. eval1 (S.If t1 t2 t3) =
  608. case eval1 t1 of
  609. Just t1' -> Just (S.If t1' t2 t3)
  610. Nothing -> Nothing
  611. -- E-APPABS, E-APP1 and E-APP2
  612. eval1 (S.App t1 t2) =
  613. if S.isValue t1
  614. then if S.isValue t2
  615. then case t1 of
  616. S.Abs x tau11 t12 -> Just (S.subst x t2 t12) -- E-APPABS
  617. _ -> Nothing
  618. else case eval1 t2 of
  619. Just t2' -> Just (S.App t1 t2') -- E-APP2
  620. Nothing -> Nothing
  621. else case eval1 t1 of
  622. Just t1' -> Just (S.App t1' t2) -- E-APP1
  623. Nothing -> Nothing
  624. eval1 (S.IntAdd t1 t2) =
  625. if S.isValue t1
  626. then case t1 of
  627. S.IntConst n1 -> if S.isValue t2
  628. then case t2 of
  629. S.IntConst n2 -> Just (S.IntConst (I.intAdd n1 n2))
  630. _ -> Nothing
  631. else case eval1 t2 of
  632. Just t2' -> Just (S.IntAdd t1 t2')
  633. Nothing -> Nothing
  634. _ -> Nothing
  635. else case eval1 t1 of
  636. Just t1' -> Just (S.IntAdd t1' t2)
  637. Nothing -> Nothing
  638. eval1 (S.IntSub t1 t2) =
  639. if S.isValue t1
  640. then case t1 of
  641. S.IntConst n1 -> if S.isValue t2
  642. then case t2 of
  643. S.IntConst n2 -> Just (S.IntConst (I.intSub n1 n2))
  644. _ -> Nothing
  645. else case eval1 t2 of
  646. Just t2' -> Just (S.IntSub t1 t2')
  647. Nothing -> Nothing
  648. _ -> Nothing
  649. else case eval1 t1 of
  650. Just t1' -> Just (S.IntSub t1' t2)
  651. Nothing -> Nothing
  652. eval1 (S.IntMul t1 t2) =
  653. if S.isValue t1
  654. then case t1 of
  655. S.IntConst n1 -> if S.isValue t2
  656. then case t2 of
  657. S.IntConst n2 -> Just (S.IntConst (I.intMul n1 n2))
  658. _ -> Nothing
  659. else case eval1 t2 of
  660. Just t2' -> Just (S.IntMul t1 t2')
  661. Nothing -> Nothing
  662. _ -> Nothing
  663. else case eval1 t1 of
  664. Just t1' -> Just (S.IntMul t1' t2)
  665. Nothing -> Nothing
  666. eval1 (S.IntDiv t1 t2) =
  667. if S.isValue t1
  668. then case t1 of
  669. S.IntConst n1 -> if S.isValue t2
  670. then case t2 of
  671. S.IntConst n2 -> Just (S.IntConst (I.intDiv n1 n2))
  672. _ -> Nothing
  673. else case eval1 t2 of
  674. Just t2' -> Just (S.IntDiv t1 t2')
  675. Nothing -> Nothing
  676. _ -> Nothing
  677. else case eval1 t1 of
  678. Just t1' -> Just (S.IntDiv t1' t2)
  679. Nothing -> Nothing
  680. eval1 (S.IntNand t1 t2) =
  681. if S.isValue t1
  682. then case t1 of
  683. S.IntConst n1 -> if S.isValue t2
  684. then case t2 of
  685. S.IntConst n2 -> Just (S.IntConst (I.intNand n1 n2))
  686. _ -> Nothing
  687. else case eval1 t2 of
  688. Just t2' -> Just (S.IntNand t1 t2')
  689. Nothing -> Nothing
  690. _ -> Nothing
  691. else case eval1 t1 of
  692. Just t1' -> Just (S.IntNand t1' t2)
  693. Nothing -> Nothing
  694. eval1 (S.IntEq t1 t2) =
  695. if S.isValue t1
  696. then case t1 of
  697. S.IntConst n1 -> if S.isValue t2
  698. then case t2 of
  699. S.IntConst n2 -> case I.intEq n1 n2 of
  700. True -> Just S.Tru
  701. _ -> Just S.Fls
  702. _ -> Nothing
  703. else case eval1 t2 of
  704. Just t2' -> Just (S.IntEq t1 t2')
  705. Nothing -> Nothing
  706. _ -> Nothing
  707. else case eval1 t1 of
  708. Just t1' -> Just (S.IntEq t1' t2)
  709. Nothing -> Nothing
  710. eval1 (S.IntLt t1 t2) =
  711. if S.isValue t1
  712. then case t1 of
  713. S.IntConst n1 -> if S.isValue t2
  714. then case t2 of
  715. S.IntConst n2 -> case I.intLt n1 n2 of
  716. True -> Just S.Tru
  717. _ -> Just S.Fls
  718. _ -> Nothing
  719. else case eval1 t2 of
  720. Just t2' -> Just (S.IntLt t1 t2')
  721. Nothing -> Nothing
  722. _ -> Nothing
  723. else case eval1 t1 of
  724. Just t1' -> Just (S.IntLt t1' t2)
  725. Nothing -> Nothing
  726. -- E-FIXBETA
  727. eval1 (S.Fix (S.Abs x tau1 t2)) =
  728. Just (S.subst x (S.Fix (S.Abs x tau1 t2)) t2)
  729. -- E-FIX
  730. eval1 (S.Fix t1) =
  731. case eval1 t1 of
  732. Just t1' -> Just (S.Fix t1')
  733. Nothing -> Nothing
  734. -- E-LETV and E-LET
  735. eval1 (S.Let x t1 t2) =
  736. if (S.isValue t1)
  737. then Just (S.subst x t1 t2) -- E-LETV
  738. else case eval1 t1 of
  739. Just t1' -> Just (S.Let x t1' t2) -- E-LET
  740. Nothing -> Nothing
  741. -- All other cases
  742. eval1 _ = Nothing
  743. eval :: S.Term -> S.Term
  744. eval t =
  745. case eval1 t of
  746. Just t' -> eval t'
  747. Nothing -> t
  748. \end{code}
  749. \subsection{Natural Semantics}
  750. \subsubsection{Formal Rules}
  751. \paragraph{}
  752. The formal rules of the natural semantics for this programming language is as follows:
  753. \[
  754. a\Downarrow v \text{\quad (\textsc{B-ClosedForm})}
  755. \]
  756. for closed form $a$, and $a$ should have no free variable inside.
  757. \[
  758. v \Downarrow v \text{\quad (\textsc{B-Value})}
  759. \]
  760. \ \\
  761. \[
  762. \frac{a\Downarrow \lambda x.a'\text{\quad} b\Downarrow v'\text{\quad} [x\mapsto v']a'\Downarrow v}{a\text{\ }b \Downarrow v}\text{\quad (\textsc{B-App})}
  763. \]
  764. \ \\
  765. \[
  766. \frac{t_1 \Downarrow \text{ true\quad } t_2 \Downarrow v_2}{\text{if } t_1 \text{ then } t_2 \text{ else } t_3 \Downarrow v_2}\text{\quad (\textsc{B-IfTrue})}
  767. \]
  768. \ \\
  769. \[
  770. \frac{t_1 \Downarrow \text{ false\quad} t_3 \Downarrow v_3}{\text{if } t_1 \text{ then } t_2 \text{ else } t_3 \Downarrow v_3}\text{\quad (\textsc{B-IfFalse})}
  771. \]
  772. \ \\
  773. \[
  774. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{+}(v_1, v_2)}{+(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntAdd})}
  775. \]
  776. \ \\
  777. \[
  778. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{\-}(v_1, v_2)}{\-(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntSub})}
  779. \]
  780. \ \\
  781. \[
  782. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{*}(v_1, v_2)}{*(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntMul})}
  783. \]
  784. \ \\
  785. \[
  786. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{/}(v_1, v_2)}{/(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntDiv})}
  787. \]
  788. \ \\
  789. \[
  790. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{\wedge}(v_1, v_2)}{\uparrow(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntNand})}
  791. \]
  792. \ \\
  793. \[
  794. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{=}(v_1, v_2)}{=(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntEq})}
  795. \]
  796. \ \\
  797. \[
  798. \frac{t_1 \Downarrow v_1\text{\quad} t_2 \Downarrow v_2\text{\quad} v = \widetilde{<}(v_1, v_2)}{<(t_1, t_2) \Downarrow v}\text{\quad (\textsc{B-IntLt})}
  799. \]
  800. \ \\
  801. \[
  802. \frac{t_1 \Downarrow v_1 \text{\quad} [x\mapsto v_1]t_2 \Downarrow v}{\text{let } x=t_1 \text{ in } t_2 \Downarrow v} \text{\quad (\textsc{B-Let})}
  803. \]
  804. \ \\
  805. \[
  806. \frac{t \Downarrow (\lambda x:T_1.\text{\ }t_{11}) \text{\quad} [x\mapsto \text{fix }(\lambda x:T_1.\text{\ }t_{11})]t_{11} \Downarrow v}{\text{fix } t \Downarrow v} \text{\quad (\textsc{B-Fix})}
  807. \]
  808. \ \\
  809. \subsubsection{Haskell Implementation}
  810. \begin{code}
  811. module NaturalSemantics where
  812. import List
  813. import qualified AbstractSyntax as S
  814. import qualified IntegerArithmetic as I
  815. eval :: S.Term -> S.Term
  816. eval (S.If t1 t2 t3) =
  817. case eval t1 of
  818. S.Tru -> eval t2 -- B-IfTrue
  819. S.Fls -> eval t3 -- B-IfFalse
  820. _ -> S.If t1 t2 t3
  821. -- B-App \& B-AppFix
  822. eval (S.App t1 t2) =
  823. if (S.isValue $ eval t1)
  824. then case eval t1 of
  825. S.Abs x tau t11 -> if ((S.isValue $ eval t2) && ((S.fv (S.Abs x tau t11)) == []))
  826. then eval (S.subst x (eval t2) t11)
  827. else S.App t1 t2
  828. _ -> S.App t1 t2
  829. else S.App t1 t2
  830. -- B-IntAdd
  831. eval (S.IntAdd t1 t2) =
  832. case eval t1 of
  833. S.IntConst v1 -> case eval t2 of
  834. S.IntConst v2 -> S.IntConst (I.intAdd v1 v2)
  835. _ -> S.IntAdd t1 t2
  836. _ -> S.IntAdd t1 t2
  837. -- B-IntSub
  838. eval (S.IntSub t1 t2) =
  839. case eval t1 of
  840. S.IntConst v1 -> case eval t2 of
  841. S.IntConst v2 -> S.IntConst (I.intSub v1 v2)
  842. _ -> S.IntSub t1 t2
  843. _ -> S.IntSub t1 t2
  844. -- B-IntMul
  845. eval (S.IntMul t1 t2) =
  846. case eval t1 of
  847. S.IntConst v1 -> case eval t2 of
  848. S.IntConst v2 -> S.IntConst (I.intMul v1 v2)
  849. _ -> S.IntSub t1 t2
  850. _ -> S.IntSub t1 t2
  851. -- B-IntDiv
  852. eval (S.IntDiv t1 t2) =
  853. case eval t1 of
  854. S.IntConst v1 -> case eval t2 of
  855. S.IntConst v2 -> S.IntConst (I.intDiv v1 v2)
  856. _ -> S.IntDiv t1 t2
  857. _ -> S.IntDiv t1 t2
  858. -- B-IntNand
  859. eval (S.IntNand t1 t2) =
  860. case eval t1 of
  861. S.IntConst v1 -> case eval t2 of
  862. S.IntConst v2 -> S.IntConst (I.intNand v1 v2)
  863. _ -> S.IntNand t1 t2
  864. _ -> S.IntNand t1 t2
  865. -- B-IntEq
  866. eval (S.IntEq t1 t2) =
  867. case eval t1 of
  868. S.IntConst v1 -> case eval t2 of
  869. S.IntConst v2 -> case I.intEq v1 v2 of
  870. True -> S.Tru
  871. False -> S.Fls
  872. _ -> S.IntEq t1 t2
  873. _ -> S.IntEq t1 t2
  874. -- B-IntLt
  875. eval (S.IntLt t1 t2) =
  876. case eval t1 of
  877. S.IntConst v1 -> case eval t2 of
  878. S.IntConst v2 -> case I.intLt v1 v2 of
  879. True -> S.Tru
  880. False -> S.Fls
  881. _ -> S.IntLt t1 t2
  882. _ -> S.IntLt t1 t2
  883. -- B-Let
  884. eval (S.Let x t1 t2) =
  885. if (S.isValue (eval t1))
  886. then if (S.isValue (eval (S.subst x (eval t1) t2)))
  887. then eval (S.subst x (eval t1) t2)
  888. else S.Let x t1 t2
  889. else S.Let x t1 t2
  890. -- B-FIX
  891. eval (S.Fix t) =
  892. if S.isValue $ eval t
  893. then case eval t of
  894. S.Abs x tau1 t11 -> if (S.isValue (eval (S.subst x (S.Fix (S.Abs x tau1 t11)) t11)))
  895. then eval (S.subst x (S.Fix (S.Abs x tau1 t11)) t11)
  896. else S.Fix t
  897. _ -> S.Fix t
  898. else S.Fix t
  899. -- B-Value and Exceptions
  900. eval t = t
  901. \end{code}
  902. \subsection{Type Checker}
  903. \subsubsection{Formal Rules}
  904. It is always good to be sure a program is well-typed before we try to evaluate it. You can use the following type checker or write your own. The typing rules are listed below:
  905. \[
  906. \frac{x:T\in \Gamma}{\Gamma \vdash x:T} \text{\quad (\textsc{T-Var})}
  907. \]
  908. \ \\
  909. \[
  910. \frac{\Gamma, x:T_1 \vdash t_2: T_2 }{\Gamma \vdash \lambda x:T_1. t_2:T_1 \rightarrow T_2} \text{\quad (\textsc{T-Abs})}
  911. \]
  912. \ \\
  913. \[
  914. \frac{\Gamma \vdash t_1: T_{11} \rightarrow T_{12} \mbox{ } \Gamma \vdash t_2:T_{11}}{\Gamma \vdash t_1\mbox{ } t_2:T_{12}} \text{\quad (\textsc{T-App})}
  915. \]
  916. \ \\
  917. \[
  918. \text{true: Bool} \text{\quad (\textsc{T-True})}
  919. \]
  920. \ \\
  921. \[
  922. \text{false: Bool} \text{\quad (\textsc{T-False})}
  923. \]
  924. \ \\
  925. \[
  926. \frac{t:Bool\mbox{ } t_2:T \mbox{ } t_3:T}{\text{if } t_1 \text{ then } t_2 \text{ else } t_3:T} \text{\quad (\textsc{T-If})}
  927. \]
  928. \ \\
  929. \[
  930. \frac{\Gamma \vdash [x \mapsto t_1]t_2: T_2\mbox{ } \Gamma \vdash t_1: T_1}{\Gamma \vdash \mbox{ let } x=t_1 \mbox{ in } t_2 : T_2}\text{\quad {(\textsc{T-LetPoly})}}
  931. \]
  932. \ \\
  933. \[
  934. \frac{\Gamma \vdash t_1: T_1\leftarrow T_1}{\Gamma \vdash \mbox{ fix } t_1 : T_1}\text{\quad {(\textsc{T-Fix})}}
  935. \]
  936. \ \\
  937. \[
  938. \frac{t_1:Int \mbox{ } t_2:Int}{+(t_1, t_2):Int}\text{\quad {(\textsc{T-IntAdd})}}
  939. \]
  940. \ \\
  941. \[
  942. \frac{t_1:Int \mbox{ } t_2:Int}{\-(t_1, t_2):Int}\text{\quad {(\textsc{T-IntSub})}}
  943. \]
  944. \ \\
  945. \[
  946. \frac{t_1:Int \mbox{ } t_2:Int}{*(t_1, t_2):Int}\text{\quad {(\textsc{T-IntMul})}}
  947. \]
  948. \ \\
  949. \[
  950. \frac{t_1:Int \mbox{ } t_2:Int}{\wedge(t_1, t_2):Int}\text{\quad {(\textsc{T-IntNand})}}
  951. \]
  952. \ \\
  953. \[
  954. \frac{t_1:Int \mbox{ } t_2:Int}{=(t_1, t_2):Bool}\text{\quad {(\textsc{T-IntEq})}}
  955. \]
  956. \ \\
  957. \[
  958. \frac{t_1:Int \mbox{ } t_2:Int}{<(t_1, t_2):Bool}\text{\quad {(\textsc{T-IntLt})}}
  959. \]
  960. \ \\
  961. \subsubsection{Haskell Implementation}
  962. \begin{code}
  963. module Typing where
  964. import qualified AbstractSyntax as S
  965. import List
  966. data Context = Empty
  967. | Bind Context S.Var S.Type
  968. deriving Eq
  969. instance Show Context where
  970. show Empty = "<>"
  971. show (Bind capGamma x tau) = show capGamma ++ "," ++ x ++ ":" ++ show tau
  972. contextLookup :: S.Var -> Context -> Maybe S.Type
  973. contextLookup x Empty = Nothing
  974. contextLookup x (Bind capGamma y tau)
  975. | x == y = Just tau
  976. | otherwise = contextLookup x capGamma
  977. typing :: Context -> S.Term -> Maybe S.Type
  978. --T-Var
  979. typing capGamma (S.Var x) = contextLookup x capGamma
  980. --T-Abs
  981. typing capGamma (S.Abs x tau_1 t2) = case typing (Bind capGamma x tau_1) t2 of
  982. Just(tp0) -> Just (S.TypeArrow tau_1 tp0)
  983. Nothing -> Nothing
  984. typing capGamma (S.App t0 t2)=
  985. case typing capGamma t0 of
  986. Just (S.TypeArrow tp tp0) -> case typing capGamma t2 of
  987. Just tp' -> if tp==tp'
  988. then Just tp0
  989. else Nothing
  990. Nothing -> Nothing
  991. _ -> Nothing
  992. --T-True
  993. typing capGamma S.Tru = Just S.TypeBool
  994. --T-False
  995. typing capGamma S.Fls = Just S.TypeBool
  996. --T-If
  997. typing capGamma (S.If t0 t2 t3)
  998. | (typing capGamma t2 == typing capGamma t3 && typing capGamma t0 == Just S.TypeBool) = typing capGamma t2
  999. | otherwise = Nothing
  1000. typing capGamma (S.IntConst _) = Just S.TypeInt
  1001. --T-LetPoly
  1002. typing capGamma (S.Let x t0 t2) =
  1003. case typing capGamma (S.subst x t0 t2) of
  1004. Just tp0 -> case typing capGamma t0 of
  1005. Just tp1 -> Just tp0
  1006. _ -> Nothing
  1007. _ -> Nothing
  1008. --T-Fix
  1009. typing capGamma (S.Fix t) =
  1010. case typing capGamma t of
  1011. Just (S.TypeArrow tp0 tp2) -> if tp0 == tp2
  1012. then Just tp0
  1013. else Nothing
  1014. _ -> Nothing
  1015. --T-IntAdd
  1016. typing capGamma (S.IntAdd t1 t2) =
  1017. case typing capGamma t1 of
  1018. Just S.TypeInt -> case typing capGamma t1 of
  1019. Just S.TypeInt -> Just S.TypeInt
  1020. Nothing -> Nothing
  1021. --T-IntSub
  1022. typing capGamma (S.IntSub t1 t2) =
  1023. case typing capGamma t1 of
  1024. Just S.TypeInt -> case typing capGamma t1 of
  1025. Just S.TypeInt -> Just S.TypeInt
  1026. Nothing -> Nothing
  1027. --T-IntMul
  1028. typing capGamma (S.IntMul t1 t2) =
  1029. case typing capGamma t1 of
  1030. Just S.TypeInt -> case typing capGamma t1 of
  1031. Just S.TypeInt -> Just S.TypeInt
  1032. Nothing -> Nothing
  1033. --T-IntDiv
  1034. typing capGamma (S.IntDiv t1 t2) =
  1035. case typing capGamma t1 of
  1036. Just S.TypeInt -> case typing capGamma t1 of
  1037. Just S.TypeInt -> Just S.TypeInt
  1038. Nothing -> Nothing
  1039. --T-IntNand
  1040. typing capGamma (S.IntNand t1 t2) =
  1041. case typing capGamma t1 of
  1042. Just S.TypeInt -> case typing capGamma t1 of
  1043. Just S.TypeInt -> Just S.TypeInt
  1044. Nothing -> Nothing
  1045. --T-IntEq
  1046. typing capGamma (S.IntEq t1 t2) =
  1047. case typing capGamma t1 of
  1048. Just S.TypeBool -> case typing capGamma t1 of
  1049. Just S.TypeBool -> Just S.TypeBool
  1050. Nothing -> Nothing
  1051. --T-IntLt
  1052. typing capGamma (S.IntLt t1 t2) =
  1053. case typing capGamma t1 of
  1054. Just S.TypeBool -> case typing capGamma t1 of
  1055. Just S.TypeBool -> Just S.TypeInt
  1056. Nothing -> Nothing
  1057. typeCheck :: S.Term -> S.Type
  1058. typeCheck t =
  1059. case typing Empty t of
  1060. Just tau -> tau
  1061. _ -> error "type error"
  1062. \end{code}
  1063. \subsubsection{Formal Rules}
  1064. \subsubsection{Haskell Implementation}
  1065. \subsection{Main Program}
  1066. \begin{code}
  1067. module Main where
  1068. import qualified System.Environment
  1069. import Data.List
  1070. import IO
  1071. import qualified AbstractSyntax as S
  1072. import qualified StructuralOperationalSemantics as E
  1073. import qualified NaturalSemantics as N
  1074. import qualified IntegerArithmetic as I
  1075. import qualified Typing as T
  1076. main :: IO()
  1077. main =
  1078. do
  1079. args <- System.Environment.getArgs
  1080. let [sourceFile] = args
  1081. source <- readFile sourceFile
  1082. let tokens = S.scan source
  1083. let term = S.parse tokens
  1084. putStrLn ("----Term----")
  1085. putStrLn (show term)
  1086. putStrLn ("----Type----")
  1087. putStrLn (show (T.typeCheck term))
  1088. putStrLn ("----Normal Form in Structureal Operational Semantics----")
  1089. putStrLn (show (E.eval term))
  1090. putStrLn ("----Normal Form of Natural Semantics----")
  1091. putStrLn (show (N.eval term))
  1092. \end{code}
  1093. \section{Reduction Semantics}
  1094. \subsection{Evaluation contexts}
  1095. \begin{code}
  1096. module EvaluationContext where
  1097. import qualified AbstractSyntax as S
  1098. data Context = Hole
  1099. | AppT Context S.Term
  1100. | AppV S.Term Context -- where Term is a value
  1101. | If Context S.Term S.Term
  1102. | IntAddT Context S.Term
  1103. | IntAddV S.Term Context
  1104. | IntSubT Context S.Term
  1105. | IntSubV S.Term Context
  1106. | IntMulT Context S.Term
  1107. | IntMulV S.Term Context
  1108. | IntDivT Context S.Term
  1109. | IntDivV S.Term Context
  1110. | IntNandT Context S.Term
  1111. | IntNandV S.Term Context
  1112. | IntEqT Context S.Term
  1113. | IntEqV S.Term Context
  1114. | IntLtT Context S.Term
  1115. | IntLtV S.Term Context
  1116. | Let S.Var Context S.Term
  1117. | Fix Context
  1118. deriving Eq
  1119. fillWithTerm :: Context -> S.Term -> S.Term
  1120. fillWithTerm c t = case c of
  1121. Hole -> t
  1122. AppT c1 t2 -> S.App (fillWithTerm c1 t) t2
  1123. AppV t1 c2 -> S.App t1 (fillWithTerm c2 t)
  1124. If c1 t2 t3 -> S.If (fillWithTerm c1 t) t2 t3
  1125. IntAddV t1 c2 -> S.IntAdd t1 (fillWithTerm c2 t)
  1126. IntAddT c1 t2 -> S.IntAdd (fillWithTerm c1 t) t2
  1127. IntSubV t1 c2 -> S.IntSub t1 (fillWithTerm c2 t)
  1128. IntSubT c1 t2 -> S.IntSub (fillWithTerm c1 t) t2
  1129. IntMulV t1 c2 -> S.IntMul t1 (fillWithTerm c2 t)
  1130. IntMulT c1 t2 -> S.IntMul (fillWithTerm c1 t) t2
  1131. IntDivV t1 c2 -> S.IntDiv t1 (fillWithTerm c2 t)
  1132. IntDivT c1 t2 -> S.IntDiv (fillWithTerm c1 t) t2
  1133. IntNandV t1 c2 -> S.IntNand t1 (fillWithTerm c2 t)
  1134. IntNandT c1 t2 -> S.IntNand (fillWithTerm c1 t) t2
  1135. IntEqV t1 c2 -> S.IntEq t1 (fillWithTerm c2 t)
  1136. IntEqT c1 t2 -> S.IntEq (fillWithTerm c1 t) t2
  1137. IntLtV t1 c2 -> S.IntLt t1 (fillWithTerm c2 t)
  1138. IntLtT c1 t2 -> S.IntLt (fillWithTerm c1 t) t2
  1139. Let x c1 t2 -> S.Let x (fillWithTerm c1 t) t2
  1140. Fix c -> S.Fix (fillWithTerm c t)
  1141. fillWithContext :: Context -> Context -> Context
  1142. fillWithContext c c' = case c of
  1143. Hole -> c'
  1144. AppT c1 t2 -> AppT (fillWithContext c1 c') t2
  1145. AppV t1 c2 -> AppV t1 (fillWithContext c2 c')
  1146. If c1 t2 t3 -> If (fillWithContext c1 c') t2 t3
  1147. IntAddV t1 c2 -> IntAddV t1 (fillWithContext c2 c')
  1148. IntAddT c1 t2 -> IntAddT (fillWithContext c1 c') t2
  1149. IntSubV t1 c2 -> IntSubV t1 (fillWithContext c2 c')
  1150. IntSubT c1 t2 -> IntSubT (fillWithContext c1 c') t2
  1151. IntMulV t1 c2 -> IntMulV t1 (fillWithContext c2 c')
  1152. IntMulT c1 t2 -> IntMulT (fillWithContext c1 c') t2
  1153. IntDivV t1 c2 -> IntDivV t1 (fillWithContext c2 c')
  1154. IntDivT c1 t2 -> IntDivT (fillWithContext c1 c') t2
  1155. IntNandV t1 c2 -> IntNandV t1 (fillWithContext c2 c')
  1156. IntNandT c1 t2 -> IntNandT (fillWithContext c1 c') t2
  1157. IntEqV t1 c2 -> IntEqV t1 (fillWithContext c2 c')
  1158. IntEqT c1 t2 -> IntEqT (fillWithContext c1 c') t2
  1159. IntLtV t1 c2 -> IntLtV t1 (fillWithContext c2 c')
  1160. IntLtT c1 t2 -> IntLtT (fillWithContext c1 c') t2
  1161. Let x c1 t2 -> Let x (fillWithContext c1 c') t2
  1162. Fix c -> Fix (fillWithContext c c')
  1163. \end{code}
  1164. \subsection{Standard reduction}
  1165. \begin{code}
  1166. module ReductionSemantics where
  1167. import qualified AbstractSyntax as S
  1168. import qualified EvaluationContext as E
  1169. import qualified StructuralOperationalSemantics as S
  1170. import qualified IntegerArithmetic as I
  1171. makeEvalContext :: S.Term -> Maybe (S.Term, E.Context)
  1172. makeEvalContext t = case t of
  1173. S.App (S.Abs x tau11 t12) t2
  1174. | S.isValue t2 -> Just (t, E.Hole)
  1175. S.App t1 t2
  1176. | S.isValue t1 -> case makeEvalContext t2 of
  1177. Just (t2', c2) -> Just (t2', (E.AppV t1 c2))
  1178. _ -> Nothing
  1179. | otherwise -> case makeEvalContext t1 of
  1180. Just(t1', c1) -> Just (t1', (E.AppT c1 t2))
  1181. _ -> Nothing
  1182. S.If (S.Tru) t2 t3 -> Just (t, E.Hole)
  1183. S.If (S.Fls) t2 t3 -> Just (t, E.Hole)
  1184. S.If t1 t2 t3 -> case makeEvalContext t1 of
  1185. Just(t1', c1) -> Just (t1', (E.If c1 t2 t3))
  1186. _ -> Nothing
  1187. S.IntAdd t1 t2
  1188. | S.isValue t1 -> case makeEvalContext t2 of
  1189. Just(t2', c2) -> Just(t2', (E.IntAddV t1 c2))
  1190. Nothing -> Just(t, E.Hole)
  1191. | otherwise -> case makeEvalContext t1 of
  1192. Just(t1', c1) -> Just(t1', (E.IntAddT c1 t2))
  1193. _ -> Nothing
  1194. S.IntSub t1 t2
  1195. | S.isValue t1 -> case makeEvalContext t2 of
  1196. Just(t2', c2) -> Just(t2', (E.IntSubV t1 c2))
  1197. Nothing -> Just(t, E.Hole)
  1198. | otherwise -> case makeEvalContext t1 of
  1199. Just(t1', c1) -> Just(t1', (E.IntSubT c1 t2))
  1200. _ -> Nothing
  1201. S.IntMul t1 t2
  1202. | S.isValue t1 -> case makeEvalContext t2 of
  1203. Just(t2', c2) -> Just(t2', (E.IntMulV t1 c2))
  1204. Nothing -> Just(t, E.Hole)
  1205. | otherwise -> case makeEvalContext t1 of
  1206. Just(t1', c1) -> Just(t1', (E.IntMulT c1 t2))
  1207. _ -> Nothing
  1208. S.IntDiv t1 t2
  1209. | S.isValue t1 -> case makeEvalContext t2 of
  1210. Just(t2', c2) -> Just(t2', (E.IntDivV t1 c2))
  1211. Nothing -> Just(t, E.Hole)
  1212. | otherwise -> case makeEvalContext t1 of
  1213. Just(t1', c1) -> Just(t1', (E.IntDivT c1 t2))
  1214. _ -> Nothing
  1215. S.IntNand t1 t2
  1216. | S.isValue t1 -> case makeEvalContext t2 of
  1217. Just(t2', c2) -> Just(t2', (E.IntNandV t1 c2))
  1218. Nothing -> Just(t, E.Hole)
  1219. | otherwise -> case makeEvalContext t1 of
  1220. Just(t1', c1) -> Just(t1', (E.IntNandT c1 t2))
  1221. _ -> Nothing
  1222. S.IntEq t1 t2
  1223. | S.isValue t1 -> case makeEvalContext t2 of
  1224. Just(t2', c2) -> Just(t2', (E.IntEqV t1 c2))
  1225. Nothing -> Just(t, E.Hole)
  1226. | otherwise -> case makeEvalContext t1 of
  1227. Just(t1', c1) -> Just(t1', (E.IntEqT c1 t2))
  1228. _ -> Nothing
  1229. S.IntLt t1 t2
  1230. | S.isValue t1 -> case makeEvalContext t2 of
  1231. Just(t2', c2) -> Just(t2', (E.IntLtV t1 c2))
  1232. Nothing -> Just(t, E.Hole)
  1233. | otherwise -> case makeEvalContext t1 of
  1234. Just(t1', c1) -> Just(t1', (E.IntLtT c1 t2))
  1235. _ -> Nothing
  1236. S.Let x t1 t2
  1237. | S.isValue t1 -> Just (t, E.Hole)
  1238. | otherwise -> case makeEvalContext t1 of
  1239. Just(t1', c1) -> Just(t1', (E.Let x c1 t2))
  1240. _ -> Nothing
  1241. S.Fix (S.Abs x tau1 t2) -> Just (t, E.Hole)
  1242. S.Fix t -> case makeEvalContext t of
  1243. Just(t', c) -> Just(t', E.Fix c)
  1244. _ -> Nothing
  1245. _ -> Nothing
  1246. makeContractum :: S.Term -> S.Term
  1247. makeContractum t = case t of
  1248. S.App (S.Abs x tau11 t12) t2 -> S.subst x t2 t12
  1249. S.If (S.Tru) t2 t3 -> t2
  1250. S.If (S.Fls) t2 t3 -> t3
  1251. S.IntAdd (S.IntConst n1) (S.IntConst n2) -> S.IntConst (I.intAdd n1 n2)
  1252. S.IntSub (S.IntConst n1) (S.IntConst n2) -> S.IntConst (I.intSub n1 n2)
  1253. S.IntMul (S.IntConst n1) (S.IntConst n2) -> S.IntConst (I.intMul n1 n2)
  1254. S.IntDiv (S.IntConst n1) (S.IntConst n2) -> S.IntConst (I.intDiv n1 n2)
  1255. S.IntNand (S.IntConst n1) (S.IntConst n2) -> S.IntConst (I.intNand n1 n2)
  1256. S.IntEq (S.IntConst n1) (S.IntConst n2) -> if I.intEq n1 n2 then S.Tru else S.Fls
  1257. S.IntLt (S.IntConst n1) (S.IntConst n2) -> if I.intLt n1 n2 then S.Tru else S.Fls
  1258. S.Let x t1 t2 -> S.subst x t1 t2
  1259. S.Fix (S.Abs x tau1 t2) -> S.subst x (S.Fix (S.Abs x tau1 t2)) t2
  1260. textualMachineStep :: S.Term -> Maybe S.Term
  1261. textualMachineStep t =
  1262. case makeEvalContext t of
  1263. Just(t1, c) -> Just (E.fillWithTerm c (makeContractum t1))
  1264. Nothing -> Nothing
  1265. textualMachineEval :: S.Term -> S.Term
  1266. textualMachineEval t =
  1267. case textualMachineStep t of
  1268. Just t' -> textualMachineEval t'
  1269. Nothing -> t
  1270. \end{code}
  1271. \section{Abstract Register Machines}
  1272. \subsection{CC Machine}
  1273. \begin{code}
  1274. module CCMachine where
  1275. import qualified AbstractSyntax as S
  1276. import qualified EvaluationContext as E
  1277. import qualified IntegerArithmetic as I
  1278. lookupHole :: E.Context -> Maybe (E.Context, E.Context)
  1279. lookupHole (E.AppT c1 t) = case c1 of
  1280. E.Hole -> Just ((E.AppT c1 t), E.Hole)
  1281. _ -> case lookupHole c1 of
  1282. Just (c2, c3) -> Just (c2, (E.AppT c3 t))
  1283. lookupHole (E.AppV v c1) = case c1 of
  1284. E.Hole -> Just ((E.AppV v c1), E.Hole)
  1285. _ -> case lookupHole c1 of
  1286. Just(c2, c3) -> Just (c2, (E.AppV v c3))
  1287. lookupHole (E.If c1 t1 t2) = case c1 of
  1288. E.Hole -> Just((E.If c1 t1 t2), E.Hole)
  1289. _ -> case lookupHole c1 of
  1290. Just(c2, c3) -> Just (c2, (E.If c3 t1 t2))
  1291. lookupHole (E.IntAddT c1 t) = case c1 of
  1292. E.Hole -> Just((E.IntAddT c1 t), E.Hole)
  1293. _ -> case lookupHole c1 of
  1294. Just(c2, c3) -> Just (c2, (E.IntAddT c3 t))
  1295. lookupHole (E.IntAddV t c1) = case c1 of
  1296. E.Hole -> Just((E.IntAddV t c1), E.Hole)
  1297. _ -> case lookupHole c1 of
  1298. Just(c2, c3) -> Just (c2, (E.IntAddV t c3))
  1299. lookupHole (E.IntSubT c1 t) = case c1 of
  1300. E.Hole -> Just((E.IntSubT c1 t), E.Hole)
  1301. _ -> case lookupHole c1 of
  1302. Just(c2, c3) -> Just (c2, (E.IntSubT c3 t))
  1303. lookupHole (E.IntSubV t c1) = case c1 of
  1304. E.Hole -> Just((E.IntSubV t c1), E.Hole)
  1305. _ -> case lookupHole c1 of
  1306. Just(c2, c3) -> Just (c2, (E.IntSubV t c3))
  1307. lookupHole (E.IntMulT c1 t) = case c1 of
  1308. E.Hole -> Just((E.IntMulT c1 t), E.Hole)
  1309. _ -> case lookupHole c1 of
  1310. Just(c2, c3) -> Just (c2, (E.IntMulT c3 t))
  1311. lookupHole (E.IntMulV t c1) = case c1 of
  1312. E.Hole -> Just((E.IntMulV t c1), E.Hole)
  1313. _ -> case lookupHole c1 of
  1314. Just(c2, c3) -> Just (c2, (E.IntMulV t c3))
  1315. lookupHole (E.IntDivT c1 t) = case c1 of
  1316. E.Hole -> Just((E.IntDivT c1 t), E.Hole)
  1317. _ -> case lookupHole c1 of
  1318. Just(c2, c3) -> Just (c2, (E.IntDivT c3 t))
  1319. lookupHole (E.IntDivV t c1) = case c1 of
  1320. E.Hole -> Just((E.IntDivV t c1), E.Hole)
  1321. _ -> case lookupHole c1 of
  1322. Just(c2, c3) -> Just (c2, (E.IntDivV t c3))
  1323. lookupHole (E.IntNandT c1 t)= case c1 of
  1324. E.Hole -> Just((E.IntNandT c1 t), E.Hole)
  1325. _ -> case lookupHole c1 of
  1326. Just(c2, c3) -> Just (c2, (E.IntNandT c3 t))
  1327. lookupHole (E.IntNandV t c1)= case c1 of
  1328. E.Hole -> Just((E.IntNandV t c1), E.Hole)
  1329. _ -> case lookupHole c1 of
  1330. Just(c2, c3) -> Just (c2, (E.IntNandV t c3))
  1331. lookupHole (E.IntEqT c1 t)= case c1 of
  1332. E.Hole -> Just((E.IntEqT c1 t), E.Hole)
  1333. _ -> case lookupHole c1 of
  1334. Just(c2, c3) -> Just (c2, (E.IntEqT c3 t))
  1335. lookupHole (E.IntEqV t c1)= case c1 of
  1336. E.Hole -> Just((E.IntEqV t c1), E.Hole)
  1337. _ -> case lookupHole c1 of
  1338. Just(c2, c3) -> Just (c2, (E.IntEqV t c3))
  1339. lookupHole (E.IntLtT c1 t)= case c1 of
  1340. E.Hole -> Just((E.IntLtT c1 t), E.Hole)
  1341. _ -> case lookupHole c1 of
  1342. Just(c2, c3) -> Just (c2, (E.IntLtT c3 t))
  1343. lookupHole (E.IntLtV t c1)= case c1 of
  1344. E.Hole -> Just((E.IntLtV t c1), E.Hole)
  1345. _ -> case lookupHole c1 of
  1346. Just(c2, c3) -> Just (c2, (E.IntLtV t c3))
  1347. lookupHole (E.Let x c1 t1)= case c1 of
  1348. E.Hole -> Just((E.Let x c1 t1), E.Hole)
  1349. _ -> case lookupHole c1 of
  1350. Just(c2, c3) -> Just (c2, (E.Let x c3 t1))
  1351. lookupHole (E.Fix c1) = case c1 of
  1352. E.Hole -> Just((E.Fix c1), E.Hole)
  1353. _ -> case lookupHole c1 of
  1354. Just(c2, c3) -> Just (c2, (E.Fix c3))
  1355. lookupHole c1 = Nothing
  1356. ccMachineStep :: (S.Term, E.Context) -> Maybe (S.Term, E.Context)
  1357. ccMachineStep (t, c) = case t of
  1358. S.App t1 t2
  1359. | not (S.isValue t1) -> Just (t1, E.fillWithContext c (E.AppT E.Hole t2)) {-cc1-}
  1360. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.AppV t1 E.Hole)) {-cc2-}
  1361. S.App (S.Abs x _ t12) t2 -> Just (S.subst x t2 t12, c) {-cc$\beta$-}
  1362. S.IntAdd t1 t2
  1363. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntAddT E.Hole t2))
  1364. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntAddV t1 E.Hole))
  1365. {-cc3-}
  1366. | otherwise -> case t1 of
  1367. S.IntConst n1 -> case t2 of
  1368. S.IntConst n2 -> Just (S.IntConst (I.intAdd n1 n2), c)
  1369. {-cc$\delta$-}
  1370. S.If (S.Tru) t2 t3 -> Just (t2, c)
  1371. S.If (S.Fls) t2 t3 -> Just (t3, c)
  1372. S.If t1 t2 t3
  1373. | not (S.isValue t1) -> Just (t1, E.fillWithContext c (E.If E.Hole t2 t3))
  1374. S.IntSub t1 t2
  1375. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntSubT E.Hole t2))
  1376. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntSubV t1 E.Hole))
  1377. {-cc3-}
  1378. | otherwise -> case t1 of
  1379. S.IntConst n1 -> case t2 of
  1380. S.IntConst n2 -> Just (S.IntConst (I.intSub n1 n2), c)
  1381. {-cc$\delta$-}
  1382. S.IntMul t1 t2
  1383. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntMulT E.Hole t2))
  1384. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntMulV t1 E.Hole))
  1385. {-cc3-}
  1386. | otherwise -> case t1 of
  1387. S.IntConst n1 -> case t2 of
  1388. S.IntConst n2 -> Just (S.IntConst (I.intMul n1 n2), c)
  1389. {-cc$\delta$-}
  1390. S.IntDiv t1 t2
  1391. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntDivT E.Hole t2))
  1392. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntDivV t1 E.Hole))
  1393. {-cc3-}
  1394. | otherwise -> case t1 of
  1395. S.IntConst n1 -> case t2 of
  1396. S.IntConst n2 -> Just (S.IntConst (I.intDiv n1 n2), c)
  1397. {-cc$\delta$-}
  1398. S.IntNand t1 t2
  1399. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntNandT E.Hole t2))
  1400. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntNandV t1 E.Hole))
  1401. {-cc3-}
  1402. | otherwise -> case t1 of
  1403. S.IntConst n1 -> case t2 of
  1404. S.IntConst n2 -> Just (S.IntConst (I.intNand n1 n2), c)
  1405. {-cc$\delta$-}
  1406. S.IntEq t1 t2
  1407. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntEqT E.Hole t2))
  1408. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntEqV t1 E.Hole))
  1409. {-cc3-}
  1410. | otherwise -> case t1 of
  1411. S.IntConst n1 -> case t2 of
  1412. S.IntConst n2 -> case I.intEq n1 n2 of
  1413. True -> Just(S.Tru, c)
  1414. _ -> Just(S.Fls, c)
  1415. {-cc$\delta$-}
  1416. S.IntLt t1 t2
  1417. | not(S.isValue t1) -> Just (t1, E.fillWithContext c (E.IntLtT E.Hole t2))
  1418. | S.isValue t1 && not (S.isValue t2) -> Just (t2, E.fillWithContext c (E.IntLtV t1 E.Hole))
  1419. {-cc3-}
  1420. | otherwise -> case t1 of
  1421. S.IntConst n1 -> case t2 of
  1422. S.IntConst n2 -> case I.intLt n1 n2 of
  1423. True -> Just(S.Tru, c)
  1424. _ -> Just(S.Fls, c)
  1425. {-cc$\delta$-}
  1426. S.Let x t1 t2
  1427. | S.isValue t1 -> Just (S.subst x t1 t2, c)
  1428. | otherwise -> Just (t1, E.fillWithContext c (E.Let x E.Hole t2))
  1429. S.Fix t
  1430. | not (S.isValue t) -> Just (t, E.fillWithContext c (E.Fix E.Hole))
  1431. | otherwise -> case t of
  1432. S.Abs x tau1 t2 -> Just (S.subst x (S.Fix (S.Abs x tau1 t2)) t2, c)
  1433. _ -> case lookupHole c of
  1434. Just (c2, c3) -> Just (E.fillWithTerm c2 t, c3)
  1435. Nothing -> Nothing
  1436. ccMachineEval :: S.Term -> S.Term
  1437. ccMachineEval t =
  1438. fst $ f (t, E.Hole)
  1439. where
  1440. f :: (S.Term, E.Context) -> (S.Term, E.Context)
  1441. f (t, c) =
  1442. case ccMachineStep (t, c) of
  1443. Just (t', c') -> f (t', c')
  1444. Nothing -> (t, c)
  1445. \end{code}
  1446. \subsection{SCC Machine}
  1447. \begin{code}
  1448. module SCCMachine where
  1449. import qualified AbstractSyntax as S
  1450. import qualified EvaluationContext as E
  1451. import qualified IntegerArithmetic as I
  1452. import qualified CCMachine as CC
  1453. dealWithContext :: (S.Term,E.Context) -> Maybe (S.Term, E.Context)
  1454. dealWithContext (t,c) = case c of
  1455. {-app-}
  1456. E.AppT E.Hole t2 -> Just (t2, E.AppV t E.Hole)
  1457. E.AppV (S.Abs x tau t') E.Hole -> Just ((S.subst x t t'),E.Hole)
  1458. {-if-}
  1459. E.If E.Hole t2 t3 -> case t of
  1460. S.Tru -> Just (t2, E.Hole)
  1461. S.Fls -> Just (t3, E.Hole)
  1462. {-add-}
  1463. E.IntAddT E.Hole t2 -> Just (t2, E.IntAddV t E.Hole)
  1464. E.IntAddV t1 E.Hole -> case t1 of
  1465. S.IntConst n1 -> case t of
  1466. S.IntConst n2 -> Just(S.IntConst (I.intAdd n1 n2),E.Hole)
  1467. _ -> Nothing
  1468. _ -> Nothing
  1469. {-sub-}
  1470. E.IntSubT E.Hole t2 -> Just (t2, E.IntSubV t E.Hole)
  1471. E.IntSubV t1 E.Hole -> case t1 of
  1472. S.IntConst n1 -> case t of
  1473. S.IntConst n2 -> Just(S.IntConst (I.intSub n1 n2),E.Hole)
  1474. _ -> Nothing
  1475. _ -> Nothing
  1476. {-mul-}
  1477. E.IntMulT E.Hole t2 -> Just (t2, E.IntMulV t E.Hole)
  1478. E.IntMulV t1 E.Hole -> case t1 of
  1479. S.IntConst n1 -> case t of
  1480. S.IntConst n2 -> Just(S.IntConst (I.intMul n1 n2),E.Hole)
  1481. _ -> Nothing
  1482. _ -> Nothing
  1483. {-div-}
  1484. E.IntDivT E.Hole t2 -> Just (t2, E.IntDivV t E.Hole)
  1485. E.IntDivV t1 E.Hole -> case t1 of
  1486. S.IntConst n1 -> case t of
  1487. S.IntConst n2 -> Just(S.IntConst (I.intDiv n1 n2),E.Hole)
  1488. _ -> Nothing
  1489. _ -> Nothing
  1490. {-nand-}
  1491. E.IntNandT E.Hole t2 -> Just (t2, E.IntNandV t E.Hole)
  1492. E.IntNandV t1 E.Hole -> case t1 of
  1493. S.IntConst n1 -> case t of
  1494. S.IntConst n2 -> Just(S.IntConst (I.intNand n1 n2),E.Hole)
  1495. _ -> Nothing
  1496. _ -> Nothing
  1497. {-eq-}
  1498. E.IntEqT E.Hole t2 -> Just (t2, E.IntEqV t E.Hole)
  1499. E.IntEqV t1 E.Hole -> case t1 of
  1500. S.IntConst n1 -> case t of
  1501. S.IntConst n2 -> case I.intEq n1 n2 of
  1502. True -> Just (S.Tru,E.Hole)
  1503. False -> Just (S.Fls,E.Hole)
  1504. _ -> Nothing
  1505. _ -> Nothing
  1506. {-lt-}
  1507. E.IntLtT E.Hole t2 -> Just (t2, E.IntLtV t E.Hole)
  1508. E.IntLtV t1 E.Hole -> case t1 of
  1509. S.IntConst n1 -> case t of
  1510. S.IntConst n2 -> case I.intLt n1 n2 of
  1511. True -> Just (S.Tru,E.Hole)
  1512. False -> Just (S.Fls,E.Hole)
  1513. _ -> Nothing
  1514. _ -> Nothing
  1515. {-let-}
  1516. E.Let x E.Hole t2 -> Just (S.subst x t t2,E.Hole)
  1517. {-fix-}
  1518. E.Fix E.Hole -> case t of
  1519. S.Abs x tau1 t2 -> Just (S.subst x (S.Fix (S.Abs x tau1 t2)) t2, E.Hole)
  1520. _ -> Nothing
  1521. _ -> Nothing
  1522. sccMachineStep :: (S.Term, E.Context) -> Maybe (S.Term, E.Context)
  1523. sccMachineStep (t,c) = case S.isValue t of
  1524. {-t is a term-}
  1525. False -> case t of
  1526. S.App t1 t2 -> Just (t1, E.fillWithContext c (E.AppT E.Hole t2))
  1527. S.If t1 t2 t3 -> Just (t1, E.fillWithContext c (E.If E.Hole t2 t3))
  1528. S.IntAdd t1 t2 -> Just (t1, E.fillWithContext c (E.IntAddT E.Hole t2))
  1529. S.IntSub t1 t2 -> Just (t1, E.fillWithContext c (E.IntSubT E.Hole t2))
  1530. S.IntMul t1 t2 -> Just (t1, E.fillWithContext c (E.IntMulT E.Hole t2))
  1531. S.IntDiv t1 t2 -> Just (t1, E.fillWithContext c (E.IntDivT E.Hole t2))
  1532. S.IntNand t1 t2 -> Just (t1, E.fillWithContext c (E.IntNandT E.Hole t2))
  1533. S.IntEq t1 t2 -> Just (t1, E.fillWithContext c (E.IntEqT E.Hole t2))
  1534. S.IntLt t1 t2 -> Just (t1,E.fillWithContext c (E.IntLtT E.Hole t2))
  1535. S.Let x t1 t2 -> Just (t1, E.fillWithContext c (E.Let x E.Hole t2))
  1536. S.Fix t -> Just (t, E.fillWithContext c (E.Fix E.Hole))
  1537. _ -> Nothing
  1538. {-t is a value-}
  1539. True -> case dealWithContext (t,c) of
  1540. Just (t',c') -> Just (t',c')
  1541. Nothing -> case c of
  1542. {-app-}
  1543. E.AppT c1 t2 -> case CC.lookupHole c1 of
  1544. Just (c',cl) -> case dealWithContext (t,c') of
  1545. Just (t',cc) -> Just (t',E.AppT (E.fillWithContext cl cc) t2)
  1546. _ -> Nothing
  1547. _ -> Nothing
  1548. E.AppV t1 c2 -> case CC.lookupHole c2 of
  1549. Just (c',cl) -> case dealWithContext (t,c') of
  1550. Just (t',cc) -> Just (t',E.AppV t1 (E.fillWithContext cl cc))
  1551. _ -> Nothing
  1552. _ -> Nothing
  1553. {-if-}
  1554. E.If c1 t2 t3 -> case CC.lookupHole c1 of
  1555. Just (c',cl) -> case dealWithContext (t,c') of
  1556. Just (t',cc) -> Just (t',E.If (E.fillWithContext cl cc) t2 t3)
  1557. _ -> Nothing
  1558. _ -> Nothing
  1559. {-add-}
  1560. E.IntAddT c1 t2 -> case CC.lookupHole c1 of
  1561. Just (c',cl) -> case dealWithContext (t,c') of
  1562. Just (t',cc) -> Just (t',E.IntAddT (E.fillWithContext cl cc) t2)
  1563. _ -> Nothing
  1564. _ -> Nothing
  1565. E.IntAddV t1 c2 -> case CC.lookupHole c2 of
  1566. Just (c',cl) -> case dealWithContext (t,c') of
  1567. Just (t',cc) -> Just (t',E.IntAddV t1 (E.fillWithContext cl cc))
  1568. _ -> Nothing
  1569. _ -> Nothing
  1570. {-sub-}
  1571. E.IntSubT c1 t2 -> case CC.lookupHole c1 of
  1572. Just (c',cl) -> case dealWithContext (t,c') of
  1573. Just (t',cc) -> Just (t',E.IntSubT (E.fillWithContext cl cc) t2)
  1574. _ -> Nothing
  1575. _ -> Nothing
  1576. E.IntSubV t1 c2 -> case CC.lookupHole c2 of
  1577. Just (c',cl) -> case dealWithContext (t,c') of
  1578. Just (t',cc) -> Just (t',E.IntSubV t1 (E.fillWithContext cl cc))
  1579. _ -> Nothing
  1580. _ -> Nothing
  1581. {-mul-}
  1582. E.IntMulT c1 t2 -> case CC.lookupHole c1 of
  1583. Just (c',cl) -> case dealWithContext (t,c') of
  1584. Just (t',cc) -> Just (t',E.IntMulT (E.fillWithContext cl cc) t2)
  1585. _ -> Nothing
  1586. _ -> Nothing
  1587. E.IntMulV t1 c2 -> case CC.lookupHole c2 of
  1588. Just (c',cl) -> case dealWithContext (t,c') of
  1589. Just (t',cc) -> Just (t',E.IntMulV t1 (E.fillWithContext cl cc))
  1590. _ -> Nothing
  1591. _ -> Nothing
  1592. {-div-}
  1593. E.IntDivT c1 t2 -> case CC.lookupHole c1 of
  1594. Just (c',cl) -> case dealWithContext (t,c') of
  1595. Just (t',cc) -> Just (t',E.IntDivT (E.fillWithContext cl cc) t2)
  1596. _ -> Nothing
  1597. _ -> Nothing
  1598. E.IntDivV t1 c2 -> case CC.lookupHole c2 of
  1599. Just (c',cl) -> case dealWithContext (t,c') of
  1600. Just (t',cc) -> Just (t',E.IntDivV t1 (E.fillWithContext cl cc))
  1601. _ -> Nothing
  1602. _ -> Nothing
  1603. {-nand-}
  1604. E.IntNandT c1 t2 -> case CC.lookupHole c1 of
  1605. Just (c',cl) -> case dealWithContext (t,c') of
  1606. Just (t',cc) -> Just (t',E.IntNandT (E.fillWithContext cl cc) t2)
  1607. _ -> Nothing
  1608. _ -> Nothing
  1609. E.IntNandV t1 c2 -> case CC.lookupHole c2 of
  1610. Just (c',cl) -> case dealWithContext (t,c') of
  1611. Just (t',cc) -> Just (t',E.IntNandV t1 (E.fillWithContext cl cc))
  1612. _ -> Nothing
  1613. _ -> Nothing
  1614. {-eq-}
  1615. E.IntEqT c1 t2 -> case CC.lookupHole c1 of
  1616. Just (c',cl) -> case dealWithContext (t,c') of
  1617. Just (t',cc) -> Just (t',E.IntEqT (E.fillWithContext cl cc) t2)
  1618. _ -> Nothing
  1619. _ -> Nothing
  1620. E.IntEqV t1 c2 -> case CC.lookupHole c2 of
  1621. Just (c',cl) -> case dealWithContext (t,c') of
  1622. Just (t',cc) -> Just (t',E.IntEqV t1 (E.fillWithContext cl cc))
  1623. _ -> Nothing
  1624. _ -> Nothing
  1625. {-lt-}
  1626. E.IntLtT c1 t2 -> case CC.lookupHole c1 of
  1627. Just (c',cl) -> case dealWithContext (t,c') of
  1628. Just (t',cc) -> Just (t',E.IntLtT (E.fillWithContext cl cc) t2)
  1629. _ -> Nothing
  1630. _ -> Nothing
  1631. E.IntLtV t1 c2 -> case CC.lookupHole c2 of
  1632. Just (c',cl) -> case dealWithContext (t,c') of
  1633. Just (t',cc) -> Just (t',E.IntLtV t1 (E.fillWithContext cl cc))
  1634. _ -> Nothing
  1635. _ -> Nothing
  1636. {-let-}
  1637. E.Let x c1 t2 -> case CC.lookupHole c1 of
  1638. Just (c',cl) -> case dealWithContext (t,c') of
  1639. Just (t',cc) -> Just (t',E.Let x (E.fillWithContext cl cc) t2)
  1640. _ -> Nothing
  1641. _ -> Nothing
  1642. {-fix-}
  1643. E.Fix c1 -> case CC.lookupHole c1 of
  1644. Just (c',cl) ->case dealWithContext (t,c') of
  1645. Just (t',cc) -> Just (t',E.Fix (E.fillWithContext cl cc))
  1646. _ -> Nothing
  1647. _ -> Nothing
  1648. _ -> Nothing
  1649. sccMachineEval :: S.Term -> S.Term
  1650. sccMachineEval t =
  1651. fst $ f (t,E.Hole)
  1652. where
  1653. f :: (S.Term, E.Context) -> (S.Term, E.Context)
  1654. f (t,c) =
  1655. case sccMachineStep (t,c) of
  1656. Just (t',c') -> f (t',c')
  1657. Nothing -> (t,c)
  1658. \end{code}
  1659. \subsection{CK Machine}
  1660. \begin{code}
  1661. module CKMachine where
  1662. import qualified AbstractSyntax as S
  1663. import qualified IntegerArithmetic as I
  1664. data Cont = MachineTerminate
  1665. | Fun S.Term Cont -- where Term is a value
  1666. | Arg S.Term Cont
  1667. | If S.Term S.Term Cont
  1668. | IntAdd1 S.Term Cont -- where Term is a value
  1669. | IntAdd2 S.Term Cont
  1670. | IntSub1 S.Term Cont
  1671. | IntSub2 S.Term Cont
  1672. | IntMul1 S.Term Cont
  1673. | IntMul2 S.Term Cont
  1674. | IntDiv1 S.Term Cont
  1675. | IntDiv2 S.Term Cont
  1676. | IntNand1 S.Term Cont
  1677. | IntNand2 S.Term Cont
  1678. | IntEq1 S.Term Cont
  1679. | IntEq2 S.Term Cont
  1680. | IntLt1 S.Term Cont
  1681. | IntLt2 S.Term Cont
  1682. | Let S.Var S.Term Cont
  1683. | Fix Cont
  1684. ckMachineStep :: (S.Term, Cont) -> Maybe (S.Term, Cont)
  1685. ckMachineStep (t,c) =
  1686. case t of
  1687. S.App t1 t2 -> Just (t1, (Arg t2 c))
  1688. S.IntAdd t1 t2 -> Just (t1, (IntAdd2 t2 c))
  1689. S.IntSub t1 t2 -> Just (t1, (IntSub2 t2 c))
  1690. S.IntMul t1 t2 -> Just (t1, (IntMul2 t2 c))
  1691. S.IntDiv t1 t2 -> Just (t1, (IntDiv2 t2 c))
  1692. S.IntNand t1 t2-> Just (t1, (IntNand2 t2 c))
  1693. S.IntEq t1 t2 -> Just (t1, (IntEq2 t2 c))
  1694. S.IntLt t1 t2 -> Just (t1, (IntLt2 t2 c))
  1695. S.If t1 t2 t3 -> Just (t1, (If t2 t3 c))
  1696. S.Tru -> case c of
  1697. If t2 t3 c' -> Just (t2, c')
  1698. _ -> Nothing
  1699. S.Fls -> case c of
  1700. If t2 t3 c' -> Just (t3, c')
  1701. _ -> Nothing
  1702. S.Let x t1 t2 -> Just (t1, Let x t2 c)
  1703. S.Fix (S.Abs x tau11 t11) -> Just (S.subst x (S.Fix (S.Abs x tau11 t11)) t11, c)
  1704. S.Fix t' -> Just (t', Fix c)
  1705. _
  1706. | S.isValue t -> case c of
  1707. Fun (S.Abs x tau11 t11) c' -> Just (S.subst x t t11, c')
  1708. Arg t2 c' -> Just (t2, Fun t c')
  1709. IntAdd1 (S.IntConst n1) c' -> case t of
  1710. S.IntConst n2 -> Just (S.IntConst (I.intAdd n1 n2), c')
  1711. _ -> Nothing
  1712. IntAdd2 t2 c' -> Just (t2, IntAdd1 t c')
  1713. IntSub1 (S.IntConst n1) c' -> case t of
  1714. S.IntConst n2 -> Just (S.IntConst (I.intSub n1 n2), c')
  1715. _ -> Nothing
  1716. IntSub2 t2 c' -> Just (t2, IntSub1 t c')
  1717. IntMul1 (S.IntConst n1) c' -> case t of
  1718. S.IntConst n2 -> Just (S.IntConst (I.intMul n1 n2), c')
  1719. _ -> Nothing
  1720. IntMul2 t2 c' -> Just (t2, IntMul1 t c')
  1721. IntDiv1 (S.IntConst n1) c' -> case t of
  1722. S.IntConst n2 -> Just (S.IntConst (I.intDiv n1 n2), c')
  1723. _ -> Nothing
  1724. IntDiv2 t2 c' -> Just (t2, IntDiv1 t c')
  1725. IntNand1 (S.IntConst n1) c'-> case t of
  1726. S.IntConst n2 -> Just (S.IntConst (I.intNand n1 n2), c')
  1727. _ -> Nothing
  1728. IntNand2 t2 c' -> Just (t2, IntNand1 t c')
  1729. IntEq1 (S.IntConst n1) c' -> case t of
  1730. S.IntConst n2 -> case I.intEq n1 n2 of
  1731. True -> Just (S.Tru, c')
  1732. _ -> Just (S.Fls, c')
  1733. _ -> Nothing
  1734. IntEq2 t2 c' -> Just (t2, IntEq1 t c')
  1735. IntLt1 (S.IntConst n1) c' -> case t of
  1736. S.IntConst n2 -> case I.intLt n1 n2 of