Line No. | Rev | Author | Line |
---|---|---|---|
1 | 1 | paulosilva | |
2 | {-# LANGUAGE GADTs, PatternSignatures #-} | ||
3 | {-# OPTIONS_GHC -Wall #-} | ||
4 | |||
5 | ------------------------------------------------------------------------------- | ||
6 | |||
7 | {- | | ||
8 | Module : Language.R.Match | ||
9 | Description : Matching algorithm for 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.Match ( | ||
22 | rMatch, | ||
23 | rSubst | ||
24 | ) where | ||
25 | |||
26 | 7 | paulosilva | import Control.MonadOr |
27 | 1 | paulosilva | import Control.Monad.Error |
28 | import Data.Maybe (listToMaybe) | ||
29 | import Language.R.Equality | ||
30 | import Language.R.Rewrite | ||
31 | import Language.R.SafeCast | ||
32 | import Language.R.Syntax | ||
33 | import Language.Type.Equality | ||
34 | import Language.Type.Syntax | ||
35 | |||
36 | ------------------------------------------------------------------------------- | ||
37 | |||
38 | data Match where | ||
39 | (:=<=:) :: R a -> R b -> Match | ||
40 | |||
41 | instance Show Match where | ||
42 | show (r :=<=: r') = show "RMatch: " ++ show r ++ " =<= " ++ show r' | ||
43 | |||
44 | ------------------------------------------------------------------------------- | ||
45 | |||
46 | 7 | paulosilva | rMatch :: MonadOr m => R a -> R b -> m [Match] |
47 | 1 | paulosilva | rMatch x@(Var _) r = return [x :=<=: r] |
48 | rMatch (NEG r) (NEG r') = do | ||
49 | rr <- rMatch r r' | ||
50 | return rr | ||
51 | rMatch (MEET r s) (MEET r' s') = do | ||
52 | rr <- rMatch r r' | ||
53 | ss <- rMatch s s' | ||
54 | return $ rr ++ ss | ||
55 | rMatch (JOIN r s) (JOIN r' s') = do | ||
56 | rr <- rMatch r r' | ||
57 | ss <- rMatch s s' | ||
58 | return $ rr ++ ss | ||
59 | rMatch (CONV r) (CONV r') = do | ||
60 | rr <- rMatch r r' | ||
61 | return rr | ||
62 | rMatch (COMP t f g) (COMP t' f' g') = do | ||
63 | guard (beq t t') | ||
64 | ff <- rMatch f f' | ||
65 | gg <- rMatch g g' | ||
66 | return $ ff ++ gg | ||
67 | rMatch (SPLIT r s) (SPLIT r' s') = do | ||
68 | rr <- rMatch r r' | ||
69 | ss <- rMatch s s' | ||
70 | return $ rr ++ ss | ||
71 | rMatch (ORD o) (ORD o') = do | ||
72 | oo <- rMatch o o' | ||
73 | return oo | ||
74 | rMatch (FUN f) (FUN f') = do | ||
75 | ff <- rMatch f f' | ||
76 | return ff | ||
77 | rMatch (LEFTSEC t s r) (LEFTSEC t' s' r') = do | ||
78 | guard (beq t t') | ||
79 | ss <- rMatch s s' | ||
80 | rr <- rMatch r r' | ||
81 | return $ ss ++ rr | ||
82 | rMatch (RIGHTSEC t s r) (RIGHTSEC t' s' r') = do | ||
83 | guard (beq t t') | ||
84 | ss <- rMatch s s' | ||
85 | rr <- rMatch r r' | ||
86 | return $ ss ++ rr | ||
87 | rMatch (APPLY t r v) (APPLY t' r' v') = do | ||
88 | guard (beq t t') | ||
89 | rr <- rMatch r r' | ||
90 | vv <- rMatch v v' | ||
91 | return $ rr ++ vv | ||
92 | rMatch (PROD r s) (PROD r' s') = do | ||
93 | rr <- rMatch r r' | ||
94 | ss <- rMatch s s' | ||
95 | return $ rr ++ ss | ||
96 | rMatch (EITHER r s) (EITHER r' s') = do | ||
97 | rr <- rMatch r r' | ||
98 | ss <- rMatch s s' | ||
99 | return $ rr ++ ss | ||
100 | rMatch (MAYBE r) (MAYBE r') = do | ||
101 | rr <- rMatch r r' | ||
102 | return rr | ||
103 | rMatch (LIST r) (LIST r') = do | ||
104 | rr <- rMatch r r' | ||
105 | return rr | ||
106 | rMatch (SET r) (SET r') = do | ||
107 | rr <- rMatch r r' | ||
108 | return rr | ||
109 | rMatch (MAP r) (MAP r') = do | ||
110 | rr <- rMatch r r' | ||
111 | return rr | ||
112 | 5 | paulosilva | rMatch (REYNOLDS r s) (REYNOLDS r' s') = do |
113 | rr <- rMatch r r' | ||
114 | ss <- rMatch s s' | ||
115 | return $ rr ++ ss | ||
116 | 1 | paulosilva | rMatch (FComp t f g) (FComp t' f' g') = do |
117 | guard (beq t t') | ||
118 | ff <- rMatch f f' | ||
119 | gg <- rMatch g g' | ||
120 | return $ ff ++ gg | ||
121 | rMatch (OComp o1 o2) (OComp o1' o2') = do | ||
122 | oo1 <- rMatch o1 o1' | ||
123 | oo2 <- rMatch o2 o2' | ||
124 | return $ oo1 ++ oo2 | ||
125 | rMatch (OConv o) (OConv o') = do | ||
126 | oo <- rMatch o o' | ||
127 | return oo | ||
128 | rMatch (OProd o) (OProd o') = do | ||
129 | oo <- rMatch o o' | ||
130 | return oo | ||
131 | rMatch (OJoin o) (OJoin o') = do | ||
132 | oo <- rMatch o o' | ||
133 | return oo | ||
134 | rMatch (OMeet o) (OMeet o') = do | ||
135 | oo <- rMatch o o' | ||
136 | return oo | ||
137 | rMatch (OMax o) (OMax o') = do | ||
138 | oo <- rMatch o o' | ||
139 | return oo | ||
140 | rMatch (OMin o) (OMin o') = do | ||
141 | oo <- rMatch o o' | ||
142 | return oo | ||
143 | rMatch f g = | ||
144 | if req f g then return [] else mzero | ||
145 | |||
146 | ------------------------------------------------------------------------------- | ||
147 | |||
148 | type RuleSimpl = GenericM [] | ||
149 | |||
150 | match2Rule :: Match -> RuleSimpl | ||
151 | match2Rule ((Var n) :=<=: r2) t (Var n') = do | ||
152 | guard (n == n') | ||
153 | r2' <- rCast [] t r2 | ||
154 | return r2' | ||
155 | match2Rule _ _ _ = mzero | ||
156 | |||
157 | ------------------------------------------------------------------------------- | ||
158 | |||
159 | rSubst :: [Match] -> Type a -> R a -> R a | ||
160 | rSubst mts t r = let (rs::[RuleSimpl]) = map match2Rule mts | ||
161 | in maybe r id . listToMaybe $ (everywhere (try (seqRules rs))) t r | ||
162 | |||
163 | ------------------------------------------------------------------------------- |