- (9.1.5) Going with the book’s “we use long function names” style:
evalRoman ⟦h t u⟧ = evalHundreds ⟦h⟧ + evalTens ⟦t⟧ + evalUnits ⟦u⟧
evalHundreds ⟦ε⟧ = 0
evalHundreds ⟦C⟧ = 100
evalHundreds ⟦CC⟧ = 200
evalHundreds ⟦CCC⟧ = 300
evalHundreds ⟦CD⟧ = 400
evalTens ⟦lt⟧ = evalLowTens ⟦lt⟧
evalTens ⟦XL⟧ = 40
evalTens ⟦L lt⟧ = 50 + evalLowTens ⟦lt⟧
evalTens ⟦XC⟧ = 90
evalLowTens ⟦ε⟧ = 0
evalLowTens ⟦lt X⟧ = evalLowTens ⟦lt⟧ + 10
evalUnits ⟦lu⟧ = evalLowUnits ⟦lu⟧
evalUnits ⟦IV⟧ = 4
evalUnits ⟦V lu⟧ = 5 + evalLowUnits ⟦lu⟧
evalUnits ⟦IX⟧ = 9
evalLowUnits ⟦ε⟧ = 0
evalLowUnits ⟦lu I⟧ = evalLowUnits ⟦lu⟧ + 1
- (9.2.6) Syntax: Add a new clause to the Answer syntax category:
Answer ::= M+ | = | +/- | sqr
Semantics: Add a new clause to the calculate semantic function:
calculate ⟦sqr⟧ (a,op,d,m) = (a,op,times(d,d),m)
- (9.3.1 a,b) Part (a) using the book's notation:
execute ⟦repeat C until E⟧ = loop
where loop sto = if evaluate ⟦E⟧ sto' then sto' else loop sto'
where sto' = execute ⟦C⟧ sto
A more conventional and concise approach:
$\mathscr{C}[\![\mathtt{repeat}\;c\;\mathtt{until}\;e]\!] = \mathit{r}\;
\mathsf{where}\;r\;\sigma =
\mathsf{let}\;\sigma' = \mathscr{C}\,c\,\sigma\;\mathsf{in}\;
\mathsf{if}\;\mathscr{E}\,e\,\sigma'\;\mathsf{then}\;\sigma'\;\mathsf{else}\;r\;\sigma'$
If you want to go with the fix point style:
$\mathscr{C}[\![\mathtt{repeat}\;c\;\mathtt{until}\;e]\!] = \mathit{fix}\;
\lambda r. \lambda \sigma.
\mathsf{let}\;\sigma' = \mathscr{C}\,c\,\sigma\;\mathsf{in}\;
\mathsf{if}\;\mathscr{E}\,e\,\sigma'\;\mathsf{then}\;\sigma'\;\mathsf{else}\;r\;\sigma'$
Part (b), also using the book’s notation:
evaluate ⟦if E1 then E2 else E3⟧ =
if evaluate ⟦E1⟧ then evaluate ⟦E2⟧ else evaluate ⟦E3⟧
In class, I mentioned you could skip the proof of semantic equivalence that was requested in Part (b), so that will not be graded.
- (9.3.9) The book uses a pretty lame syntax for variables. As mentioned in the helper, it is much nicer to use the grammar I used in my notes on Logic. So here’s my concrete syntax:
var → "p" | "q" | "r" | var "′"
formula → "true" | "false" | var
| "¬" forumula
| "(" formula "∧" formula ")"
| "(" formula "∨" formula ")"
| "(" formula "⊃" formula ")"
| "(" formula "≡" formula ")"
The abstract syntax is:
v: Var
f: Formula = true | false | ¬f | f ∧ f | f ∨ f | f ⊃ f | f ≡ f
The semantics requires formulas to be evaluated against an interpretation which is the logician’s word for a “memory” or “store” that maps variables to truth values. This domain looks like:
$\mathsf{Interpretation} = \mathsf{Var} \rightarrow \mathbb{B}$
and the semantic function for evaluating formulas is:
$\mathscr{E}: \mathsf{Formula} \rightarrow \mathsf{Interpretation} \rightarrow \mathbb{B}$
Defined like so:
$\begin{array}{l}
\mathscr{E} [\![ \mathtt{true} ]\!] \varphi = T \\
\mathscr{E} [\![ \mathtt{false} ]\!] \varphi = F \\
\mathscr{E} [\![ p ]\!] \varphi = \varphi\;p \\
\mathscr{E} [\![ \neg p ]\!] \varphi = \neg\mathscr{E} [\![ p ]\!]\varphi \\
\mathscr{E} [\![ p \wedge q ]\!] \varphi = \mathscr{E} [\![ p ]\!]\varphi \wedge \mathscr{E} [\![ q ]\!]\varphi \\
\mathscr{E} [\![ p \vee q ]\!] \varphi = \mathscr{E} [\![ p ]\!]\varphi \vee \mathscr{E} [\![ q ]\!]\varphi \\
\mathscr{E} [\![ p \supset q ]\!] \varphi = \mathscr{E} [\![ p ]\!]\varphi \supset \mathscr{E} [\![ q ]\!]\varphi \\
\mathscr{E} [\![ p \equiv q ]\!] \varphi = \mathscr{E} [\![ p ]\!]\varphi \equiv \mathscr{E} [\![ q ]\!]\varphi
\end{array}$
- (10.1.2) It’s just:
$\mathsf{Tree} = \mathbb{N} \cup (\mathsf{Tree} \times \mathsf{Tree})$