never executed always true always false
1 {-# LANGUAGE QuasiQuotes #-}
2
3 module Conjure.Representations.Function.Function1DPartial ( function1DPartial ) where
4
5 -- conjure
6 import Conjure.Prelude
7 import Conjure.Language
8 import Conjure.Language.ZeroVal ( zeroVal, EnumerateDomain )
9 import Conjure.Representations.Internal
10 import Conjure.Representations.Common
11 import Conjure.Representations.Function.Function1D ( domainValues )
12
13 -- unordered-containers
14 import qualified Data.HashMap.Strict as M
15
16
17 function1DPartial :: forall m . (MonadFailDoc m, NameGen m, EnumerateDomain m) => Representation m
18 function1DPartial = Representation chck downD structuralCons downC up symmetryOrdering
19
20 where
21
22 chck :: TypeOf_ReprCheck m
23 chck f (DomainFunction _
24 attrs@(FunctionAttr _ PartialityAttr_Partial _)
25 innerDomainFr
26 innerDomainTo) | domainCanIndexMatrix innerDomainFr = do
27 innerDomainFr' <- f innerDomainFr
28 innerDomainTo' <- f innerDomainTo
29 return [ DomainFunction Function_1DPartial attrs fr to
30 | fr <- innerDomainFr'
31 , to <- innerDomainTo'
32 ]
33 chck _ _ = return []
34
35 nameFlags = mkOutName (Just "Flags")
36 nameValues = mkOutName (Just "Values")
37
38 downD :: TypeOf_DownD m
39 downD (name, domain@(DomainFunction Function_1DPartial
40 (FunctionAttr _ PartialityAttr_Partial _)
41 innerDomainFr
42 innerDomainTo)) | domainCanIndexMatrix innerDomainFr = return $ Just
43 [ ( nameFlags domain name
44 , DomainMatrix
45 (forgetRepr innerDomainFr)
46 DomainBool
47 )
48 , ( nameValues domain name
49 , DomainMatrix
50 (forgetRepr innerDomainFr)
51 innerDomainTo
52 )
53 ]
54 downD _ = na "{downD} Function1DPartial"
55
56 structuralCons :: TypeOf_Structural m
57 structuralCons f downX1
58 (DomainFunction Function_1DPartial
59 (FunctionAttr sizeAttr PartialityAttr_Partial jectivityAttr)
60 innerDomainFr
61 innerDomainTo) | domainCanIndexMatrix innerDomainFr = do
62
63 let injectiveCons flags values = do
64 (iPat, i) <- quantifiedVar
65 (jPat, j) <- quantifiedVar
66 return $ return $ -- list
67 [essence|
68 and([ &values[&i] != &values[&j]
69 | &iPat : &innerDomainFr
70 , &jPat : &innerDomainFr
71 , &i .< &j
72 , &flags[&i]
73 , &flags[&j]
74 ])
75 |]
76
77 let surjectiveCons flags values = do
78 (iPat, i) <- quantifiedVar
79 (jPat, j) <- quantifiedVar
80 return $ return $ -- list
81 [essence|
82 forAll &iPat : &innerDomainTo .
83 exists &jPat : &innerDomainFr .
84 &flags[&j] /\ &values[&j] = &i
85 |]
86
87 let jectivityCons flags values = case jectivityAttr of
88 JectivityAttr_None -> return []
89 JectivityAttr_Injective -> injectiveCons flags values
90 JectivityAttr_Surjective -> surjectiveCons flags values
91 JectivityAttr_Bijective -> (++) <$> injectiveCons flags values
92 <*> surjectiveCons flags values
93
94 let cardinality flags = do
95 (iPat, i) <- quantifiedVar
96 return [essence| sum &iPat : &innerDomainFr . toInt(&flags[&i]) |]
97
98 let dontCareInactives flags values = do
99 (iPat, i) <- quantifiedVar
100 return $ return $ -- list
101 [essence|
102 forAll &iPat : &innerDomainFr . &flags[&i] = false ->
103 dontCare(&values[&i])
104 |]
105
106 let innerStructuralCons flags values = do
107 (iPat, i) <- quantifiedVarOverDomain (forgetRepr innerDomainFr)
108 let activeZone b = [essence| forAll &iPat : &innerDomainFr . &flags[&i] -> &b |]
109
110 -- preparing structural constraints for the inner guys
111 innerStructuralConsGen <- f innerDomainTo
112
113 let inLoop = [essence| &values[&i] |]
114 outs <- innerStructuralConsGen inLoop
115 return (map activeZone outs)
116
117 return $ \ func -> do
118 refs <- downX1 func
119 case refs of
120 [flags,values] ->
121 concat <$> sequence
122 [ jectivityCons flags values
123 , dontCareInactives flags values
124 , mkSizeCons sizeAttr <$> cardinality flags
125 , innerStructuralCons flags values
126 ]
127 _ -> na "{structuralCons} Function1DPartial"
128
129 structuralCons _ _ _ = na "{structuralCons} Function1DPartial"
130
131 downC :: TypeOf_DownC m
132 downC ( name
133 , domain@(DomainFunction Function_1DPartial
134 (FunctionAttr _ PartialityAttr_Partial _)
135 innerDomainFr
136 innerDomainTo)
137 , viewConstantFunction -> Just vals_
138 ) | domainCanIndexMatrix innerDomainFr = do
139 let vals = M.fromList vals_
140 z <- zeroVal innerDomainTo
141 froms <- domainValues innerDomainFr
142 (flagsOut, valsOut) <- unzip <$> sequence
143 [ val
144 | fr <- froms
145 , let val = case M.lookup fr vals of
146 Nothing -> return (ConstantBool False, z)
147 Just v -> return (ConstantBool True , v)
148 ]
149 return $ Just
150 [ ( nameFlags domain name
151 , DomainMatrix
152 (forgetRepr innerDomainFr)
153 DomainBool
154 , ConstantAbstract $ AbsLitMatrix
155 (forgetRepr innerDomainFr)
156 flagsOut
157 )
158 , ( nameValues domain name
159 , DomainMatrix
160 (forgetRepr innerDomainFr)
161 innerDomainTo
162 , ConstantAbstract $ AbsLitMatrix
163 (forgetRepr innerDomainFr)
164 valsOut
165 )
166 ]
167 downC _ = na "{downC} Function1DPartial"
168
169 up :: TypeOf_Up m
170 up ctxt (name, domain@(DomainFunction Function_1DPartial
171 (FunctionAttr _ PartialityAttr_Partial _)
172 innerDomainFr _)) =
173 case (lookup (nameFlags domain name) ctxt, lookup (nameValues domain name) ctxt) of
174 ( Just (ConstantAbstract (AbsLitMatrix _ flagMatrix)) ,
175 Just (ConstantAbstract (AbsLitMatrix _ valuesMatrix)) ) -> do
176 froms <- domainValues innerDomainFr
177 functionValues <- forM (zip3 flagMatrix froms valuesMatrix) $ \ (flag, from, to) ->
178 case viewConstantBool flag of
179 Just b -> return $ if b then Just (from,to) else Nothing
180 Nothing -> failDoc $ vcat [ "Expected a boolean, but got:" <++> pretty flag
181 , "When working on:" <+> pretty name
182 , "With domain:" <+> pretty domain
183 ]
184 return ( name, ConstantAbstract $ AbsLitFunction $ catMaybes functionValues )
185 (Nothing, _) -> failDoc $ vcat $
186 [ "(in Function1DPartial up 1)"
187 , "No value for:" <+> pretty (nameFlags domain name)
188 , "When working on:" <+> pretty name
189 , "With domain:" <+> pretty domain
190 ] ++
191 ("Bindings in context:" : prettyContext ctxt)
192 (_, Nothing) -> failDoc $ vcat $
193 [ "(in Function1DPartial up 2)"
194 , "No value for:" <+> pretty (nameValues domain name)
195 , "When working on:" <+> pretty name
196 , "With domain:" <+> pretty domain
197 ] ++
198 ("Bindings in context:" : prettyContext ctxt)
199 _ -> failDoc $ vcat $
200 [ "Expected matrix literals for:" <+> pretty (nameFlags domain name)
201 <+> "and" <+> pretty (nameValues domain name)
202 , "When working on:" <+> pretty name
203 , "With domain:" <+> pretty domain
204 ] ++
205 ("Bindings in context:" : prettyContext ctxt)
206 up _ _ = na "{up} Function1DPartial"
207
208 symmetryOrdering :: TypeOf_SymmetryOrdering m
209 symmetryOrdering innerSO downX1 inp domain = do
210 [flags, values] <- downX1 inp
211 Just [_, (_, DomainMatrix innerDomainFr innerDomainTo)] <- downD ("SO", domain)
212 (iPat, i) <- quantifiedVar
213 soValues <- innerSO downX1 [essence| &values[&i] |] innerDomainTo
214 return
215 [essence|
216 [ ( -toInt(&flags[&i])
217 , &soValues
218 )
219 | &iPat : &innerDomainFr
220 ]
221 |]
222