1
\section{Conv: Checking convertibility}
3
%if False %% only to be seen by the Haskell compiler
11
This module implements convertibility. There are functions which
12
checks convertibility for values, type values and vector of values.
13
The convertibility functions take one extra integer argument which is
15
fresh generic values. This is used when we check if two functional values \texttt{f}
16
and \texttt{g} are convertible, we just check if \texttt{f u = g u} for a generic
19
The following functions are defined:
21
\item |eq n u v w| checks if \texttt{v = w : u}
22
\item |eqs n u vs ws| checks if \texttt{vs = ws : u'},
23
where \texttt{u'} is the argument types of \texttt{u}
24
\item |eqT n u v| checks if \texttt{u = v} as types.
27
We first have to define the monad for error checking:
29
data G a = Ok a | Fail String
31
instance Monad G where
37
The convertibility functions will use a |gensym| function to generate
38
fresh generic values. The expression |gensym n s u| will generate an
39
empty application from the head built up from the (unique) index |n|,
40
the name |s| and the type |u|.
42
gensym :: Int -> Name -> Val -> G Val
43
gensym n s u = return (mvar (Gen n s u))
46
\subsubsection{Type convertibility}
48
eqT :: Int -> Val -> Val -> G ()
50
To check if two types are convertible, we have the following cases:
52
\item \texttt{Set} is equal to \texttt{Set}.
54
eqT _ Set Set = return ()
56
\item Two functional types are equal if their parts are equal, so to check whether
57
\texttt{Fun a f = Fun a' f'} we first check if \texttt{a = a'} and then check if
58
\texttt{f u = f' u}, where \texttt{u} is a new generic value.
60
eqT n (Fun a1 f1) (Fun a2 f2) =
64
eqT (n+1) (f1 u) (f2 u)
66
\item For the remaining cases, we check if they are convertible as values in \texttt{Set}
69
eqT n u1 u2 = eq n Set u1 u2
75
\subsubsection{Convertibility of values in a type}
77
eq :: Int -> Val -> Val -> Val -> G ()
79
To check if two objects in a type are equal, we have the following cases:
81
\item If the type is a functional type, then to check \texttt{u = v : Fun a f},
82
we check if \texttt{u w = v w : f w} for a generic value \texttt{w} of type \texttt{a}.
84
eq n (Fun a f) u1 u2 =
87
eq (n+1) (f u) (app u1 u) (app u2 u)
89
\item Otherwise, we must check two applications. We then check that the heads are equal
90
and the arguments are equal.
92
eq n _ (App h1 us1) (App h2 us2) =
93
if eqH h1 h2 then eqs n (typH h1) us1 us2
96
\item In all other cases, the objects are not convertible.
98
eq _ _ _ _ = fail "eq"
103
\subsubsection{Convertibility of vectors}
106
eqs :: Int -> Val -> [Val] -> [Val] -> G ()
109
The expression |eqs n u vs ws| checks if two vectors |vs| and
110
|ws| are equal and fits as arguments to the functional type |u|. We have
113
\item If the two vectors are empty, then we are done.
115
eqs n a [] [] = return ()
117
\item If the two vectors are nonempty, then to check if
118
\texttt{u1:us1 = u2:us2 : Fun a f} we first check if \texttt{u1 = u2 : a} and
119
then check \texttt{us1 = us2 : f u1}.
121
eqs n (Fun a f) (u1:us1) (u2:us2) =
126
\item In all other cases the vectors are not convertible.
130
eqs _ _ _ _ = fail "eqs"