From 5138e3f81713d9b7ffe24e1132e9eed1243065d9 Mon Sep 17 00:00:00 2001 From: Yuri Tatishchev Date: Sat, 21 Feb 2026 21:09:49 -0800 Subject: [PATCH] hw2: init --- hw2/hs/WhileInterp.hs | 80 +++++++++++ hw2/hs/mapExample.hs | 12 ++ hw2/hs/test.hs | 36 +++++ hw2/while-semantics.pdf | Bin 0 -> 44199 bytes hw2/while-semantics.tex | 292 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 420 insertions(+) create mode 100644 hw2/hs/WhileInterp.hs create mode 100644 hw2/hs/mapExample.hs create mode 100644 hw2/hs/test.hs create mode 100644 hw2/while-semantics.pdf create mode 100644 hw2/while-semantics.tex diff --git a/hw2/hs/WhileInterp.hs b/hw2/hs/WhileInterp.hs new file mode 100644 index 0000000..271de6c --- /dev/null +++ b/hw2/hs/WhileInterp.hs @@ -0,0 +1,80 @@ +{- + Name: + Class: CS 252 + Assigment: HW2 + Date: + Description: +-} + + +module WhileInterp ( + Expression(..), + Binop(..), + Value(..), + testProgram, + run +) where + +import Data.Map (Map) +import qualified Data.Map as Map + +-- We represent variables as strings. +type Variable = String + +-- The store is an associative map from variables to values. +-- (The store roughly corresponds with the heap in a language like Java). +type Store = Map Variable Value + +data Expression = + Var Variable -- x + | Val Value -- v + | Assign Variable Expression -- x := e + | Sequence Expression Expression -- e1; e2 + | Op Binop Expression Expression + | If Expression Expression Expression -- if e1 then e2 else e3 + | While Expression Expression -- while (e1) e2 + deriving (Show) + +data Binop = + Plus -- + :: Int -> Int -> Int + | Minus -- - :: Int -> Int -> Int + | Times -- * :: Int -> Int -> Int + | Divide -- / :: Int -> Int -> Int + | Gt -- > :: Int -> Int -> Bool + | Ge -- >= :: Int -> Int -> Bool + | Lt -- < :: Int -> Int -> Bool + | Le -- <= :: Int -> Int -> Bool + deriving (Show) + +data Value = + IntVal Int + | BoolVal Bool + deriving (Show) + + +-- This function will be useful for defining binary operations. +-- The first case is done for you. +-- Be sure to explicitly check for a divide by 0 and throw an error. +applyOp :: Binop -> Value -> Value -> Value +applyOp Plus (IntVal i) (IntVal j) = IntVal $ i + j +applyOp _ _ _ = error "TBD" + + +-- Implement this function according to the specified semantics +evaluate :: Expression -> Store -> (Value, Store) +evaluate (Op o e1 e2) s = + let (v1,s1) = evaluate e1 s + (v2,s') = evaluate e2 s1 + in (applyOp o v1 v2, s') +evaluate _ _ = error "TBD" + + +-- Evaluates a program with an initially empty state +run :: Expression -> (Value, Store) +run prog = evaluate prog Map.empty + +-- The same as run, but only returns the Store +testProgram :: Expression -> Store +testProgram prog = snd $ run prog + + diff --git a/hw2/hs/mapExample.hs b/hw2/hs/mapExample.hs new file mode 100644 index 0000000..00f02d2 --- /dev/null +++ b/hw2/hs/mapExample.hs @@ -0,0 +1,12 @@ +import Data.Map (Map) +import qualified Data.Map as Map + +m = Map.empty + +m' = Map.insert "a" 42 m + +main = do + case (Map.lookup "a" m') of + Just i -> putStrLn $ show i + _ -> error "Key is not in the map" + diff --git a/hw2/hs/test.hs b/hw2/hs/test.hs new file mode 100644 index 0000000..3d3e3ca --- /dev/null +++ b/hw2/hs/test.hs @@ -0,0 +1,36 @@ +import WhileInterp + +-- Here are a few tests that you can use to check your implementation. +w_test = (Sequence (Assign "X" (Op Plus (Op Minus (Op Plus (Val (IntVal 1)) (Val (IntVal 2))) (Val (IntVal 3))) (Op Plus (Val (IntVal 1)) (Val (IntVal 3))))) (Sequence (Assign "Y" (Val (IntVal 0))) (While (Op Gt (Var "X") (Val (IntVal 0))) (Sequence (Assign "Y" (Op Plus (Var "Y") (Var "X"))) (Assign "X" (Op Minus (Var "X") (Val (IntVal 1)))))))) + +w_fact = (Sequence (Assign "N" (Val (IntVal 2))) (Sequence (Assign "F" (Val (IntVal 1))) (While (Op Gt (Var "N") (Val (IntVal 0))) (Sequence (Assign "X" (Var "N")) (Sequence (Assign "Z" (Var "F")) (Sequence (While (Op Gt (Var "X") (Val (IntVal 1))) (Sequence (Assign "F" (Op Plus (Var "Z") (Var "F"))) (Assign "X" (Op Minus (Var "X") (Val (IntVal 1)))))) (Assign "N" (Op Minus (Var "N") (Val (IntVal 1)))))))))) + +testUnit :: IO () +testUnit = do + -- Should be: (IntVal 1,fromList []) + putStrLn $ show $ WhileInterp.run (Val (IntVal 1)) + -- Should be: (BoolVal True,fromList [("X",BoolVal True)]) + putStrLn $ show $ WhileInterp.run (Assign "X" (Val (BoolVal True))) + -- Should be: (IntVal 2,fromList []) + putStrLn $ show $ WhileInterp.run (Sequence (Val (IntVal 1)) (Val (IntVal 2))) + -- Should be: (IntVal 11,fromList []) + putStrLn $ show $ WhileInterp.run (Op Plus (Val (IntVal 9)) (Val (IntVal 2))) + -- Should be: (IntVal 1,fromList []) + putStrLn $ show $ WhileInterp.run (If (Val (BoolVal True)) (Val (IntVal 1)) (Val (IntVal 2))) + -- Should be: (IntVal 2,fromList []) + putStrLn $ show $ WhileInterp.run (If (Val (BoolVal False)) (Val (IntVal 1)) (Val (IntVal 2))) + -- Should be: (BoolVal False,fromList []) + putStrLn $ show $ WhileInterp.run (While (Val (BoolVal False)) (Val (IntVal 42))) + -- Should be: (IntVal 666,fromList [("X",IntVal 666)]) + putStrLn $ show $ WhileInterp.run (Sequence + (Assign "X" (Val (IntVal 666))) + (Var "X")) + +main :: IO () +main = do + testUnit + -- Should be: fromList [("X",IntVal 0),("Y",IntVal 10)] + putStrLn $ show $ WhileInterp.testProgram w_test + -- Should be: fromList [("F",IntVal 2),("N",IntVal 0),("X",IntVal 1),("Z",IntVal 2)] + putStrLn $ show $ WhileInterp.testProgram w_fact + diff --git a/hw2/while-semantics.pdf b/hw2/while-semantics.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ae02da6b0676747fbd30fbb456e62d50288dfe61 GIT binary patch literal 44199 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 ~|~ >= ~|~ < ~|~ <= & \mbox{\emph{Binary operators}} \\ +\end{array} +\] +\end{figure} + +The language for WHILE is given in Figure~\ref{fig:lang}. +Unlike the Bool* language we discussed previously, +WHILE supports \emph{mutable references}. +The state of these references is maintained in a \emph{store}, +a mapping of references to values. +(``Store'' can be thought of as a synonym for heap.) +Once we have mutable references, other language constructs become more useful, +such as sequencing operations ($e_1;e_2$). + + + +%--------- +\section{Small-step semantics} + +\newcommand{\ssrule}[3]{ + \rel{#1} & + \frac{\strut\begin{array}{@{}c@{}} #2 \end{array}} + {\strut\begin{array}{@{}c@{}} #3 \end{array}} + \\~\\ +} +%\newcommand{\sstep}[4]{\ctxt[{#1}],{#2} \rightarrow \ctxt[{#3}],{#4}} +%\newcommand{\sstepraw}[4]{{#1},{#2} \rightarrow {#3},{#4}} +\newcommand{\sstep}[4]{{#1},{#2} \rightarrow {#3},{#4}} +\newcommand{\ctxt}{C} + +The small-step semantics for WHILE are given in Figure~\ref{fig:smallstep}. +%For the sake of brevity, these rules use \emph{evaluation contexts} ($\ctxt$), +%which specify which \emph{redex} will be evaluated next. +%The evaluation rules then apply to the ``hole'' ($\bullet$) in this context. +% +Most of these rules are fairly straightforward, but there are a couple of points +to note with the $\rel{ss-while}$ rule. +First of all, this is the only rule that makes a more complex expression +when it has finished. +(This rule is much cleaner when specified with the big-step operational semantics.) + +Secondly, note the final value of this expression once the while loop completes. +It will \emph{always} be {\false} when it completes. +We could have created a special value, such as {\tt null}, +or we could have made the while loop a statement that returns no value. +Both choices, however, would complicate our language needlessly. + + +%-------------- +\section{YOUR ASSIGNMENT} +\newcommand{\bstep}[4]{{#1},{#2} \Downarrow {#3},{#4}} + +\noindent +{\bf Part 1:} +Rewrite the operational semantic rules for WHILE in \LaTeX\ +to use big-step operational semantics instead. +Submit both your \LaTeX\ source and the generated PDF file. + +Extend your semantics with features to handle boolean values. +{\bf Do not treat these a binary operators.} +Specifically, add support for: +\begin{compactitem} + \item {\tt and} + \item {\tt or} + \item {\tt not} +\end{compactitem} + +The exact behavior of these new features is up to you, +but should seem reasonable to most programmers. + +\bigskip +\noindent +{\bf Part 2:} +Once you have your semantics defined, +download {\tt WhileInterp.hs} and implement the {\tt evaluate} function, +as well as any additional functions you need. +Your implementation must be consistent with your operational semantics, +{\it including your extensions for {\tt and}, {\tt or}, and {\tt not}}. +Also, you may not change any type signatures provided in the file. + +Finally, implement the interpreter to match your semantics. + +\bigskip +\noindent +{\bf Zip all files together into {\tt hw2.zip} and submit to Canvas.} + + + + + +%\begin{figure}[H]\label{fig:smallstep} +%\caption{Small-step semantics for WHILE} +%{\bf Runtime Syntax:} +%\[ +%\begin{array}{rclcl} +% \ctxt & \in & {Context} \quad & ::= & \quad \ctxt; e +% ~|~ \ctxt ~op~ e +% ~|~ v ~op~ \ctxt +% ~|~ \assign{x}{\ctxt} +% ~|~ \ife{\ctxt}{e_1}{e_2} +% ~|~ \bullet \\ +% \sigma & \in & {Store} \quad & = & \quad {variable} ~\rightarrow ~v \\ +% \\ +%\end{array} +%\] +%{\bf Evaluation Rules:~~~ \fbox{$\sstepraw{e}{\sigma}{e'}{\sigma'}$}} \\ +%\[ +%\begin{array}{cc} +%\begin{array}{r@{\qquad}l} +%\ssrule{ss-var}{ +% x \in domain(\sigma) \qquad \sigma(x)=v +%}{ +% \sstep{x}{\sigma}{v}{\sigma} +%} +%\ssrule{ss-assign}{ +%}{ +% \sstep{\assign{x}{v}}{\sigma}{v}{\sigma[x:=v]} +%} +%\ssrule{ss-op}{ +% v = v_1 ~op~ v_2 +%}{ +% \sstep{v_1~op~v_2}{\sigma}{v}{\sigma} +%} +%\end{array} +% & +%\begin{array}{r@{\qquad}l} +%\ssrule{ss-seq}{ +%}{ +% \sstep{v;e}{\sigma}{e}{\sigma} +%} +%\ssrule{ss-iftrue}{ +%}{ +% \sstep{\ife{\true}{e_1}{e_2}}{\sigma}{e_1}{\sigma} +%} +%\ssrule{ss-iffalse}{ +%}{ +% \sstep{\ife{\false}{e_1}{e_2}}{\sigma}{e_2}{\sigma} +%} +%\ssrule{ss-while}{ +%}{ +% \sstep{\whilee{e_1}{e_2}}{\sigma}{\ife{e_1}{e_2;\whilee{e_1}{e_2}}{\false}}{\sigma} +%} +%\end{array} +%\end{array} +%\] +%\end{figure} +% + +\begin{figure}[H]\label{fig:smallstep} +\caption{Small-step semantics for WHILE} +{\bf Runtime Syntax:} +\[ +\begin{array}{rclcl} + \sigma & \in & {Store} \quad & = & \quad {variable} ~\rightarrow ~v \\ + \\ +\end{array} +\] +{\bf Evaluation Rules:~~~ \fbox{$\sstep{e}{\sigma}{e'}{\sigma'}$}} \\ +\[ +%\begin{array}{cc} +\begin{array}{r@{\qquad}l} +\ssrule{ss-seqctx}{ + \sstep{e_1}{\sigma}{e_1'}{\sigma'} +}{ + \sstep{e_1;e_2}{\sigma}{e_1';e_2}{\sigma'} +} +\ssrule{ss-seq}{ +}{ + \sstep{v;e}{\sigma}{e}{\sigma} +} +\ssrule{ss-opctx1}{ + \sstep{e_1}{\sigma}{e_1'}{\sigma'} +}{ + \sstep{e_1~op~e_2}{\sigma}{e_1'~op~e_2}{\sigma'} +} +\ssrule{ss-opctx2}{ + \sstep{e_2}{\sigma}{e_2'}{\sigma'} +}{ + \sstep{v_1~op~e_2}{\sigma}{v_1~op~e_2'}{\sigma'} +} +\ssrule{ss-op}{ + v = v_1 ~op~ v_2 +}{ + \sstep{v_1~op~v_2}{\sigma}{v}{\sigma} +} +\end{array} +\begin{array}{r@{\qquad}l} +\ssrule{ss-var}{ + x \in domain(\sigma) \qquad \sigma(x)=v +}{ + \sstep{x}{\sigma}{v}{\sigma} +} +\ssrule{ss-assignctx}{ + \sstep{e_1}{\sigma}{e_1'}{\sigma'} +}{ + \sstep{\assign{x}{e}}{\sigma}{\assign{x}{e'}}{\sigma'} +} +\ssrule{ss-assign}{ +}{ + \sstep{\assign{x}{v}}{\sigma}{v}{\sigma[x:=v]} +} +\ssrule{ss-iftrue}{ +}{ + \sstep{\ife{\true}{e_1}{e_2}}{\sigma}{e_1}{\sigma} +} +\ssrule{ss-iffalse}{ +}{ + \sstep{\ife{\false}{e_1}{e_2}}{\sigma}{e_2}{\sigma} +} +\end{array} +\] +\[ +\begin{array}{r@{\qquad}l} +\ssrule{ss-ifctx}{ + \sstep{e_1}{\sigma}{e_1'}{\sigma'} +}{ + \sstep{\ife{e_1}{e_2}{e_3}}{\sigma}{\ife{e_1'}{e_2}{e_3}}{\sigma'} +} +\ssrule{ss-while}{ +}{ + \sstep{\whilee{e_1}{e_2}}{\sigma}{\ife{e_1}{e_2;\whilee{e_1}{e_2}}{\false}}{\sigma} +} +\end{array} +\] +\end{figure} + + +\end{document} +