Subversion

Galculator

?curdirlinks? -

Blame information for rev 7

Line No. Rev Author Line
1 1 paulosilva  
2 {-# LANGUAGE GADTs, FlexibleContexts #-}
3 {-# OPTIONS_GHC -Wall #-}
4  
5 -------------------------------------------------------------------------------
6  
7 {- |
8 Module      :  Language.R.TypeInference
9 Description :  Type inference for the expression representation.
10 Copyright   :  (c) Paulo Silva
11 License     :  LGPL
12  
13 Maintainer  :  paufil@di.uminho.pt
14 Stability   :  experimental
15 Portability :  portable
16  
17 -}
18  
19 -------------------------------------------------------------------------------
20  
21 module Language.R.TypeInference (
22    infer,
23    inferBin,
24    catchInfer,
25    InfEnv
26  ) where
27  
28 import Control.GalcError
29 import Control.Monad.Error
30 import Control.Monad.Fresh
31 import Control.Monad.State
32 import Data.Env
33 import Data.Existential
34 import Data.List
35 import qualified Data.Map as Map
36 import Language.R.SafeCast
37 import Language.R.Syntax
38 import Language.R.SyntaxADT
39 import Language.Type.Constraint
40 import Language.Type.Syntax
41 import Language.Type.Unification
42  
43 -------------------------------------------------------------------------------
44  
45 7 paulosilva infer :: (MonadError GalcError m, MonadFresh [String] String m) --, MonadOr m)  
46 1 paulosilva       => S -> m RType
47 infer s = evalStateT (infer' s) emptyEnv
48  
49 -------------------------------------------------------------------------------
50  
51 type InfEnv = Env TypeBox
52  
53 -------------------------------------------------------------------------------
54  
55 catchInfer :: (Show s, MonadError GalcError m) => s -> m a -> m a
56 catchInfer a f = f `catchError` (\e -> throwError $ InferenceError e (show a))
57  
58 -------------------------------------------------------------------------------
59  
60 addVariableEnv :: MonadState InfEnv m => String -> TypeBox -> m ()
61 addVariableEnv s t = modify (addEnv s t)
62  
63 -------------------------------------------------------------------------------
64  
65 updateEnvM :: (MonadError GalcError m, MonadState InfEnv m)
66           => [Constraint] -> InfEnv -> m ()
67 updateEnvM constr =
68   put . fmap ( \(Hide t) -> maybe (Hide t) id (typeRewrite constr t) )
69  
70 -------------------------------------------------------------------------------
71  
72 getUnifications :: [InfEnv] -> [Constraint]
73 getUnifications = aux . concatMap toList
74   where
75     aux :: [(String,TypeBox)] -> [Constraint]
76     aux [] = []
77     aux ((n, Hide t):xs) =
78       (map (\(_, Hide t') -> t :=: t') . filter ((==) n . fst) $ xs) ++ aux xs
79  
80 -------------------------------------------------------------------------------
81  
82 getFreshT :: MonadFresh [String] String m => m (Type Var)
83 getFreshT = getFreshLift (TVar . ('t':))
84  
85 -------------------------------------------------------------------------------
86 infer' :: (
87            MonadFresh [String] String m,
88            MonadError GalcError m,
89            MonadState InfEnv m
90            )
91        => S -> m RType
92 -------------------------------------------------------------------------------
93 infer' (RefS _ _) = throwError $ ImpossibleError
94 -------------------------------------------------------------------------------
95 infer' (RefExtS _ d) = return d
96 -------------------------------------------------------------------------------
97 infer' (BotS _) = do
98   t1 <- getFreshT
99   t2 <- getFreshT
100   return $ Exists (Rel t1 t2) BOT
101 -------------------------------------------------------------------------------
102 infer' (TopS _) = do
103   t1 <- getFreshT
104   t2 <- getFreshT
105   return $ Exists (Rel t1 t2) TOP
106 -------------------------------------------------------------------------------
107 infer' a@(NegS _ ra) = catchInfer a $ do
108   (Exists tr r, envR) <- inferUni ra
109   t1 <- getFreshT; t2 <- getFreshT
110   constr <- unify [tr :=: Rel t1 t2]
111 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
112   Hide t2'' <- typeRewriteE constr t2
113 1 paulosilva   r' <- rCast constr (Rel t1'' t2'') r
114   updateEnvM constr envR
115   return $ Exists (Rel t1'' t2'') (NEG r')
116 -------------------------------------------------------------------------------
117 infer' a@(MeetS _ r1a r2a) = catchInfer a $ do
118   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
119   t1 <- getFreshT; t2 <- getFreshT; t1' <- getFreshT; t2' <- getFreshT
120   constr <- unify $
121     [tr1 :=: Rel t1 t2, tr2 :=: Rel t1' t2', t1 :=: t1', t2 :=: t2'] ++ unif
122 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
123   Hide t2'' <- typeRewriteE constr t2
124 1 paulosilva   r1' <- rCast constr (Rel t1'' t2'') r1
125   r2' <- rCast constr (Rel t1'' t2'') r2
126   updateEnvM constr envR
127   return $ Exists (Rel t1'' t2'') (MEET r1' r2')
128 -------------------------------------------------------------------------------
129 infer' a@(JoinS _ r1a r2a) = catchInfer a $ do
130   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
131   t1 <- getFreshT; t2 <- getFreshT; t1' <- getFreshT; t2' <- getFreshT
132   constr <- unify $
133     [tr1 :=: Rel t1 t2, tr2 :=: Rel t1' t2', t1 :=: t1', t2 :=: t2'] ++ unif
134 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
135   Hide t2'' <- typeRewriteE constr t2
136 1 paulosilva   r1' <- rCast constr (Rel t1'' t2'') r1
137   r2' <- rCast constr (Rel t1'' t2'') r2
138   updateEnvM constr envR
139   return $ Exists (Rel t1'' t2'') (JOIN r1' r2')
140 -------------------------------------------------------------------------------
141 infer' (IdS _) = do
142   t <- getFreshT
143   return $ Exists (Rel t t) ID
144 -------------------------------------------------------------------------------
145 infer' a@(ConvS _ ra) = catchInfer a $ do
146   (Exists tr r, envR) <- inferUni ra
147   t1 <- getFreshT; t2 <- getFreshT
148   constr <- unify [tr :=: Rel t1 t2]
149 7 paulosilva   Hide t1' <- typeRewriteE constr t1
150   Hide t2' <- typeRewriteE constr t2
151 1 paulosilva   r' <- rCast constr (Rel t1' t2') r
152   updateEnvM constr envR
153   return $ Exists (Rel t2' t1') (CONV r')
154 -------------------------------------------------------------------------------
155 infer' a@(CompS _ r1a r2a) = catchInfer a $ do
156   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
157   t1 <- getFreshT; t2 <- getFreshT; t2' <- getFreshT; t3 <- getFreshT
158 7 paulosilva   constr <-  unify $
159 1 paulosilva     [tr1 :=: Rel t3 t2, tr2 :=: Rel t2' t1, t2 :=: t2'] ++ unif
160 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
161   Hide t2'' <- typeRewriteE constr t2
162   Hide t3'' <- typeRewriteE constr t3
163 1 paulosilva   r1' <- rCast constr (Rel t3'' t2'') r1
164   r2' <- rCast constr (Rel t2'' t1'') r2
165   updateEnvM constr envR
166   return $ Exists (Rel t3'' t1'') (COMP t2'' r1' r2')
167 -------------------------------------------------------------------------------
168 infer' a@(SplitS _ r1a r2a) = catchInfer a $ do
169   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
170   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t1' <- getFreshT
171   constr <- unify $
172     [tr1 :=: Rel t2 t1, tr2 :=: Rel t3 t1', t1 :=: t1'] ++ unif
173 7 paulosilva   Hide t1''  <- typeRewriteE constr t1
174   Hide t2''  <- typeRewriteE constr t2
175   Hide t3''  <- typeRewriteE constr t3
176 1 paulosilva   r1' <- rCast constr (Rel t2'' t1'') r1
177   r2' <- rCast constr (Rel t3'' t1'') r2
178   updateEnvM constr envR
179   return $ Exists (Rel (Prod t2'' t3'') t1'') (SPLIT r1' r2')
180 -------------------------------------------------------------------------------
181 infer' a@(OrdS _ ra) = catchInfer a $ do
182   (Exists tr r, envR) <- inferUni ra
183   t <- getFreshT
184   constr <- unify [tr :=: Ord t]
185 7 paulosilva   Hide t'' <- typeRewriteE constr t
186 1 paulosilva   r' <- rCast constr (Ord t'') r
187   updateEnvM constr envR
188   return $ Exists (Rel t'' t'') (ORD r')
189 -------------------------------------------------------------------------------
190 infer' a@(FunS _ ra) = catchInfer a $ do
191   (Exists tr r, envR) <- inferUni ra
192   t1 <- getFreshT; t2 <- getFreshT
193   constr <- unify [tr :=: Fun t2 t1]
194 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
195   Hide t2'' <- typeRewriteE constr t2
196 1 paulosilva   r' <- rCast constr (Fun t2'' t1'') r
197   updateEnvM constr envR
198   return $ Exists (Rel t2'' t1'') (FUN r')
199 -------------------------------------------------------------------------------
200 infer' a@(LeftsecS _ r1a r2a) = catchInfer a $ do
201   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
202   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
203   constr <- unify $ [tr1 :=: Fun t1 (Prod t2 t3), t2 :=: tr2] ++ unif
204 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
205   Hide t2'' <- typeRewriteE constr t2
206   Hide t3'' <- typeRewriteE constr t3
207 1 paulosilva   r2' <- rCast constr t2'' r2
208   r1' <- rCast constr (Fun t1'' (Prod t2'' t3'')) r1
209   updateEnvM constr envR
210   return $ Exists (Fun t1'' t3'') (LEFTSEC t2'' r1' r2')
211 -------------------------------------------------------------------------------
212 infer' a@(RightsecS _ r1a r2a) = catchInfer a $ do
213   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
214   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
215   constr <- unify $ [tr1 :=: Fun t1 (Prod t2 t3), t3 :=: tr2] ++ unif
216 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
217   Hide t2'' <- typeRewriteE constr t2
218   Hide t3'' <- typeRewriteE constr t3
219 1 paulosilva   r2' <- rCast constr t3'' r2
220   r1' <- rCast constr (Fun t1'' (Prod t2'' t3'')) r1
221   updateEnvM constr envR
222   return $ Exists (Fun t1'' t2'') (RIGHTSEC t3'' r1' r2')
223 -------------------------------------------------------------------------------
224 infer' a@(ApplyS _ r1a r2a) = catchInfer a $ do
225   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
226   t1 <- getFreshT; t2 <- getFreshT
227   constr <- unify $ [tr1 :=: Fun t1 t2, t2 :=: tr2] ++ unif
228 7 paulosilva   Hide t2'' <- typeRewriteE constr t2
229   Hide t1'' <- typeRewriteE constr t1
230 1 paulosilva   r1' <- rCast constr (Fun t1'' t2'') r1
231   r2' <- rCast constr t2'' r2
232   updateEnvM constr envR
233   return $ Exists t1'' (APPLY t2'' r1' r2')
234 -------------------------------------------------------------------------------
235 infer' (DefS _ n (Hide t)) = return $ Exists t (DEF n t)
236 -------------------------------------------------------------------------------
237 infer' (VarS _ n) = do
238   t <- getFreshT
239   addVariableEnv n (Hide t)
240   return $ Exists t (Var n)
241 -------------------------------------------------------------------------------
242 infer' a@(ProdS _ r1a r2a) = catchInfer a $ do
243   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
244   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
245   constr <- unify $ [tr1 :=: Rel t3 t1, tr2 :=: Rel t4 t2] ++ unif
246 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
247   Hide t2'' <- typeRewriteE constr t2
248   Hide t3'' <- typeRewriteE constr t3
249   Hide t4'' <- typeRewriteE constr t4
250 1 paulosilva   r1' <- rCast constr (Rel t3'' t1'') r1
251   r2' <- rCast constr (Rel t4'' t2'') r2
252   updateEnvM constr envR
253   return $ Exists (Rel (Prod t3'' t4'') (Prod t1'' t2'')) (PROD r1' r2')
254 -------------------------------------------------------------------------------
255 infer' a@(EitherS _ r1a r2a) = catchInfer a $ do
256   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
257   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
258   constr <- unify $ [tr1 :=: Rel t3 t1, tr2 :=: Rel t4 t2] ++ unif
259 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
260   Hide t2'' <- typeRewriteE constr t2
261   Hide t3'' <- typeRewriteE constr t3
262   Hide t4'' <- typeRewriteE constr t4
263 1 paulosilva   r1' <- rCast constr (Rel t3'' t1'') r1
264   r2' <- rCast constr (Rel t4'' t2'') r2
265   updateEnvM constr envR
266   return $ Exists (Rel (Either t3'' t4'') (Either t1'' t2'')) (EITHER r1' r2')
267 -------------------------------------------------------------------------------
268 infer' a@(MaybeS _ ra) = catchInfer a $ do
269   (Exists tr r, envR) <- inferUni ra
270   t1 <- getFreshT; t2 <- getFreshT
271   constr <- unify [tr :=: Rel t2 t1]
272 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
273   Hide t2'' <- typeRewriteE constr t2
274 1 paulosilva   r1' <- rCast constr (Rel t2'' t1'') r
275   updateEnvM constr envR
276   return $ Exists (Rel (Maybe t2'') (Maybe t1'')) (MAYBE r1')
277 -------------------------------------------------------------------------------
278 infer' a@(ListS _ ra) = catchInfer a $ do
279   (Exists tr r, envR) <- inferUni ra
280   t1 <- getFreshT; t2 <- getFreshT
281   constr <- unify [tr :=: Rel t2 t1]
282 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
283   Hide t2'' <- typeRewriteE constr t2
284 1 paulosilva   r1' <- rCast constr (Rel t2'' t1'') r
285   updateEnvM constr envR
286   return $ Exists (Rel (List t2'') (List t1'')) (LIST r1')
287 -------------------------------------------------------------------------------
288 infer' a@(SetS _ ra) = catchInfer a $ do
289   (Exists tr r, envR) <- inferUni ra
290   t1 <- getFreshT; t2 <- getFreshT
291   constr <- unify [tr :=: Rel t2 t1]
292 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
293   Hide t2'' <- typeRewriteE constr t2
294 1 paulosilva   r1' <- rCast constr (Rel t2'' t1'') r
295   updateEnvM constr envR
296   return $ Exists (Rel (Set t2'') (Set t1'')) (SET r1')
297 -------------------------------------------------------------------------------
298 infer' a@(MapS _ ra) = catchInfer a $ do
299   (Exists tr r, envR) <- inferUni ra
300   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
301   constr <- unify [tr :=: Rel t2 t1]
302 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
303   Hide t2'' <- typeRewriteE constr t2
304 1 paulosilva   r1' <- rCast constr (Rel t2'' t1'') r
305   updateEnvM constr envR
306   return $ Exists (Rel (Map t3 t2'') (Map t3 t1'')) (MAP r1')
307 -------------------------------------------------------------------------------
308 5 paulosilva infer' a@(ReynoldsS _ r1a r2a) = catchInfer a $ do
309   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
310   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
311   constr <- unify $ [tr1 :=: Rel t2 t1, tr2 :=: Rel t4 t3] ++ unif
312 7 paulosilva   Hide t1' <- typeRewriteE constr t1
313   Hide t2' <- typeRewriteE constr t2
314   Hide t3' <- typeRewriteE constr t3
315   Hide t4' <- typeRewriteE constr t4
316 5 paulosilva   r1' <- rCast constr (Rel t2' t1') r1
317   r2' <- rCast constr (Rel t4' t3') r2
318   updateEnvM constr envR
319   return $ Exists (Rel (Fun t2' t4') (Fun t1' t3')) (REYNOLDS r1' r2')
320 -------------------------------------------------------------------------------
321 1 paulosilva infer' (FIdS _) = do
322   t <- getFreshT
323   return $ Exists (Fun t t) FId
324 -------------------------------------------------------------------------------
325 infer' a@(FCompS _ r1a r2a) = catchInfer a $ do
326   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
327   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t2' <- getFreshT
328   constr <- unify $
329     [tr1 :=: Fun t1 t2, tr2 :=: Fun t2' t3, t2 :=: t2'] ++ unif
330 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
331   Hide t2'' <- typeRewriteE constr t2
332   Hide t3'' <- typeRewriteE constr t3
333 1 paulosilva   r1' <- rCast constr (Fun t1'' t2'') r1
334   r2' <- rCast constr (Fun t2'' t3'') r2
335   updateEnvM constr envR
336   return $ Exists (Fun t1'' t3'') (FComp t2'' r1' r2')
337 -------------------------------------------------------------------------------
338 infer' (OIdS _) = do
339   t <- getFreshT
340   return $ Exists (Ord t) OId
341 -------------------------------------------------------------------------------
342 infer' a@(OCompS _ r1a r2a) = catchInfer a $ do
343   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
344   t <- getFreshT; t' <- getFreshT
345   constr <- unify $ [tr1 :=: Ord t, tr2 :=: Ord t', t :=: t'] ++ unif
346 7 paulosilva   Hide t'' <- typeRewriteE constr t
347 1 paulosilva   r1' <- rCast constr (Ord t'') r1
348   r2' <- rCast constr (Ord t'') r2
349   updateEnvM constr envR
350   return $ Exists (Ord t'') (OComp r1' r2')
351 -------------------------------------------------------------------------------
352 infer' a@(OConvS _ ra) = catchInfer a $ do
353   (Exists tr r, envR) <- inferUni ra
354   t <- getFreshT
355   constr <- unify [tr :=: Ord t]
356 7 paulosilva   Hide t'' <- typeRewriteE constr t
357 1 paulosilva   r' <- rCast constr (Ord t'') r
358   updateEnvM constr envR
359   return $ Exists (Ord t'') (OConv r')
360 -------------------------------------------------------------------------------
361 infer' a@(OProdS _ ra) = catchInfer a $ do
362   (Exists tr r, envR) <- inferUni ra
363   t <- getFreshT
364   constr <- unify [tr :=: Ord t]
365 7 paulosilva   Hide t'' <- typeRewriteE constr t
366 1 paulosilva   r' <- rCast constr (Ord t'') r
367   updateEnvM constr envR
368   return $ Exists (Ord (Prod t'' t'')) (OProd r')
369 -------------------------------------------------------------------------------
370 infer' a@(OJoinS _ ra) = catchInfer a $ do
371   (Exists tr r, envR) <- inferUni ra
372   t <- getFreshT
373   constr <- unify [tr :=: Ord t]
374 7 paulosilva   Hide t'' <- typeRewriteE constr t
375 1 paulosilva   r' <- rCast constr (Ord t'') r
376   updateEnvM constr envR
377   return $ Exists (Fun t'' (Prod t'' t'')) (OJoin r')
378 -------------------------------------------------------------------------------
379 infer' a@(OMeetS _ ra) = catchInfer a $ do
380   (Exists tr r, envR) <- inferUni ra
381   t <- getFreshT
382   constr <- unify [tr :=: Ord t]
383 7 paulosilva   Hide t'' <- typeRewriteE constr t
384 1 paulosilva   r' <- rCast constr (Ord t'') r
385   updateEnvM constr envR
386   return $ Exists (Fun t'' (Prod t'' t'')) (OMeet r')
387 -------------------------------------------------------------------------------
388 infer' a@(OMaxS _ ra) = catchInfer a $ do
389   (Exists tr r, envR) <- inferUni ra
390   t <- getFreshT
391   constr <- unify [tr :=: Ord t]
392 7 paulosilva   Hide t'' <- typeRewriteE constr t
393 1 paulosilva   r' <- rCast constr (Ord t'') r
394   updateEnvM constr envR
395   return $ Exists t'' (OMax r')
396 -------------------------------------------------------------------------------
397 infer' a@(OMinS _ ra) = catchInfer a $ do
398   (Exists tr r, envR) <- inferUni ra
399   t <- getFreshT
400   constr <- unify [tr :=: Ord t]
401 7 paulosilva   Hide t'' <- typeRewriteE constr t
402 1 paulosilva   r' <- rCast constr (Ord t'') r
403   updateEnvM constr envR
404   return $ Exists t'' (OMin r')
405 -------------------------------------------------------------------------------
406 infer' a@(GDefS _ n f1a f2a o1a o2a) = catchInfer a $ do
407   (Exists tf1 f1, envF1) <- inferUni f1a
408   (Exists tf2 f2, envF2) <- inferUni f2a
409   (Exists to1 o1, envO1) <- inferUni o1a
410   (Exists to2 o2, envO2) <- inferUni o2a
411   t1   <- getFreshT; t2   <- getFreshT
412   t1'  <- getFreshT; t2'  <- getFreshT
413   t1'' <- getFreshT; t2'' <- getFreshT
414   let envR = envF1 `Map.union` envF2 `Map.union` envO1 `Map.union` envO2
415       unif = getUnifications [envF1,envF2,envO1,envO2]
416   constr <- unify $
417     [tf1 :=: Fun t1 t2, tf2 :=: Fun t2' t1', to1 :=: Ord t1'', to2 :=: Ord t2'',
418      t1 :=: t1', t1' :=: t1'', t2 :=: t2', t2' :=: t2''] ++ unif
419 7 paulosilva   Hide t1''' <- typeRewriteE constr t1
420   Hide t2''' <- typeRewriteE constr t2
421 1 paulosilva   f1' <- rCast constr (Fun t1''' t2''') f1
422   f2' <- rCast constr (Fun t2''' t1''') f2
423   o1' <- rCast constr (Ord t1''') o1
424   o2' <- rCast constr (Ord t2''') o2
425   updateEnvM constr envR
426   return $ Exists (GC t1''' t2''') (GDef n f1' f2' o1' o2')
427 -------------------------------------------------------------------------------
428 infer' (GIdS _) = do
429   t <- getFreshT
430   return $ Exists (GC t t) GId
431 -------------------------------------------------------------------------------
432 infer' a@(GCompS _ r1a r2a) = catchInfer a $ do
433   (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
434   t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t2' <- getFreshT
435   constr <- unify $
436     [tr1 :=: GC t1 t2, tr2 :=: GC t2' t3, t2 :=: t2'] ++ unif
437 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
438   Hide t2'' <- typeRewriteE constr t2
439   Hide t3'' <- typeRewriteE constr t3
440 1 paulosilva   r1' <- rCast constr (GC t1'' t2'') r1
441   r2' <- rCast constr (GC t2'' t3'') r2
442   updateEnvM constr envR
443   return $ Exists (GC t1'' t3'') (GComp t2'' r1' r2')
444 -------------------------------------------------------------------------------
445 infer' a@(GConvS _ ra) = catchInfer a $ do
446   (Exists tr r, envR) <- inferUni ra
447   t1 <- getFreshT; t2 <- getFreshT
448   constr <- unify [tr :=: GC t1 t2]
449 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
450   Hide t2'' <- typeRewriteE constr t2
451 1 paulosilva   r' <- rCast constr (GC t1'' t2'') r
452   updateEnvM constr envR
453   return $ Exists (GC t2'' t1'') (GConv r')
454 -------------------------------------------------------------------------------
455 infer' a@(GLAdjS _ ra) = catchInfer a $ do
456   (Exists tr r, envR) <- inferUni ra
457   t1 <- getFreshT; t2 <- getFreshT
458   constr <- unify [tr :=: GC t1 t2]
459 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
460   Hide t2'' <- typeRewriteE constr t2
461 1 paulosilva   r' <- rCast constr (GC t1'' t2'') r
462   updateEnvM constr envR
463   return $ Exists (Fun t1'' t2'') (GLAdj r')
464 -------------------------------------------------------------------------------
465 infer' a@(GUAdjS _ ra) = catchInfer a $ do
466   (Exists tr r, envR) <- inferUni ra
467   t1 <- getFreshT; t2 <- getFreshT
468   constr <- unify [tr :=: GC t1 t2]
469 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
470   Hide t2'' <- typeRewriteE constr t2
471 1 paulosilva   r' <- rCast constr (GC t1'' t2'') r
472   updateEnvM constr envR
473   return $ Exists (Fun t2'' t1'') (GUAdj r')
474 -------------------------------------------------------------------------------
475 infer' a@(GLOrdS _ ra) = catchInfer a $ do
476   (Exists tr r, envR) <- inferUni ra
477   t1 <- getFreshT; t2 <- getFreshT
478   constr <- unify [tr :=: GC t1 t2]
479 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
480   Hide t2'' <- typeRewriteE constr t2
481 1 paulosilva   r' <- rCast constr (GC t1'' t2'') r
482   updateEnvM constr envR
483   return $ Exists (Ord t1'') (GLOrd t2'' r')
484 -------------------------------------------------------------------------------
485 infer' a@(GUOrdS _ ra) = catchInfer a $ do
486   (Exists tr r, envR) <- inferUni ra
487   t1 <- getFreshT; t2 <- getFreshT
488   constr <- unify [tr :=: GC t1 t2]
489 7 paulosilva   Hide t1'' <- typeRewriteE constr t1
490   Hide t2'' <- typeRewriteE constr t2
491 1 paulosilva   r' <- rCast constr (GC t1'' t2'') r
492   updateEnvM constr envR
493   return $ Exists (Ord t2'') (GUOrd t1'' r')
494 -------------------------------------------------------------------------------
495  
496 7 paulosilva inferUni :: (MonadError GalcError m,
497 1 paulosilva              MonadState InfEnv m,
498              MonadFresh [String] String m)
499          => S -> m (RType, InfEnv)
500 inferUni r = do
501   x <- infer' r
502   envR <- get
503   put emptyEnv
504   return (x, envR)
505  
506 -------------------------------------------------------------------------------
507  
508 7 paulosilva inferBin :: (MonadError GalcError m,
509 1 paulosilva              MonadState InfEnv m,
510              MonadFresh [String] String m)
511          => S -> S -> m (RType, RType, [Constraint], InfEnv)
512 inferBin r1 r2 = do
513   (x, envR1) <- inferUni r1
514   (y, envR2) <- inferUni r2
515   let envR = envR1 `Map.union` envR2
516       unif = getUnifications [envR1,envR2]
517   return (x,y,unif,envR)
518  
519 -------------------------------------------------------------------------------
520  

Theme by Vikram Singh | Powered by WebSVN v2.3.3