@@ -189,7 +189,7 @@ instance Monoid d => Mon.Monoid (DepTestRslt d) where
189
189
mappend (MissingDeps d) (MissingDeps d') = MissingDeps (d `mappend` d')
190
190
191
191
192
- data BT a = BTN a | BTB ( BT a ) ( BT a ) -- very simple binary tree
192
+ data Tree a = Tree a [ Tree a ]
193
193
194
194
195
195
-- | Try to find a flag assignment that satisfies the constraints of all trees.
@@ -224,10 +224,7 @@ resolveWithFlags ::
224
224
-> Either [Dependency ] (TargetSet PDTagged , FlagAssignment )
225
225
-- ^ Either the missing dependencies (error case), or a pair of
226
226
-- (set of build targets with dependencies, chosen flag assignments)
227
- resolveWithFlags dom os arch impl constrs trees checkDeps =
228
- case try dom [] of
229
- Right r -> Right r
230
- Left dbt -> Left $ findShortest dbt
227
+ resolveWithFlags dom os arch impl constrs trees checkDeps = explore $ build dom []
231
228
where
232
229
extraConstrs = toDepMap constrs
233
230
@@ -241,44 +238,53 @@ resolveWithFlags dom os arch impl constrs trees checkDeps =
241
238
-- either succeeds or returns a binary tree with the missing dependencies
242
239
-- encountered in each run. Since the tree is constructed lazily, we
243
240
-- avoid some computation overhead in the successful case.
244
- try [] flags =
241
+ explore :: Tree FlagAssignment
242
+ -> Either [Dependency ] (TargetSet PDTagged , FlagAssignment )
243
+ explore (Tree flags ts) =
245
244
let targetSet = TargetSet $ flip map simplifiedTrees $
246
245
-- apply additional constraints to all dependencies
247
246
first (`constrainBy` extraConstrs) .
248
247
simplifyCondTree (env flags)
249
248
deps = overallDependencies targetSet
250
249
in case checkDeps (fromDepMap deps) of
251
- DepOk -> Right (targetSet, flags)
252
- MissingDeps mds -> Left (BTN mds)
253
-
254
- try ((n, vals): rest) flags =
255
- tryAll $ map (\ v -> try rest ((n, v): flags)) vals
256
-
250
+ DepOk | null ts -> Right (targetSet, flags)
251
+ | otherwise -> tryAll $ map explore ts
252
+ MissingDeps mds -> Left mds
253
+
254
+ build :: [(FlagName , [Bool ])]
255
+ -> FlagAssignment
256
+ -> Tree FlagAssignment
257
+ build [] flags = Tree flags []
258
+ build ((n, vals): rest) flags =
259
+ Tree flags $ map (\ v -> build rest ((n, v): flags)) vals
260
+
261
+ tryAll :: [Either [a ] b ] -> Either [a ] b
257
262
tryAll = foldr mp mz
258
263
259
264
-- special version of `mplus' for our local purposes
260
- mp (Left xs) (Left ys) = (Left (BTB xs ys))
261
- mp (Left _) m@ (Right _) = m
265
+ mp :: Either [a ] b -> Either [a ] b -> Either [a ] b
262
266
mp m@ (Right _) _ = m
267
+ mp _ m@ (Right _) = m
268
+ mp (Left xs) (Left ys) = let shortest = findShortest xs ys
269
+ in shortest `seq` Left shortest
263
270
264
271
-- `mzero'
265
- mz = Left (BTN [] )
272
+ mz :: Either [a ] b
273
+ mz = Left []
266
274
275
+ env :: FlagAssignment -> FlagName -> Either FlagName Bool
267
276
env flags flag = (maybe (Left flag) Right . lookup flag) flags
268
277
269
278
-- for the error case we inspect our lazy tree of missing dependencies and
270
279
-- pick the shortest list of missing dependencies
271
- findShortest (BTN x) = x
272
- findShortest (BTB lt rt) =
273
- let l = findShortest lt
274
- r = findShortest rt
275
- in case (l,r) of
276
- ([] , xs) -> xs -- [] is too short
277
- (xs, [] ) -> xs
278
- ([x], _) -> [x] -- single elem is optimum
279
- (_, [x]) -> [x]
280
- (xs, ys) -> if lazyLengthCmp xs ys
281
- then xs else ys
280
+ findShortest l r =
281
+ case (l,r) of
282
+ ([] , xs) -> xs -- [] is too short
283
+ (xs, [] ) -> xs
284
+ ([x], _) -> [x] -- single elem is optimum
285
+ (_, [x]) -> [x]
286
+ (xs, ys) -> if lazyLengthCmp xs ys
287
+ then xs else ys
282
288
-- lazy variant of @\xs ys -> length xs <= length ys@
283
289
lazyLengthCmp [] _ = True
284
290
lazyLengthCmp _ [] = False
@@ -301,6 +307,8 @@ toDepMap ds =
301
307
fromDepMap :: DependencyMap -> [Dependency ]
302
308
fromDepMap m = [ Dependency p vr | (p,vr) <- toList (unDependencyMap m) ]
303
309
310
+ -- | Flattens a CondTree using a partial flag assignment. When a condition
311
+ -- cannot be evaluated, both branches are ignored.
304
312
simplifyCondTree :: (Monoid a , Monoid d ) =>
305
313
(v -> Either v Bool )
306
314
-> CondTree v d a
@@ -312,7 +320,7 @@ simplifyCondTree env (CondNode a d ifs) =
312
320
case simplifyCondition cnd env of
313
321
(Lit True , _) -> Just $ simplifyCondTree env t
314
322
(Lit False , _) -> fmap (simplifyCondTree env) me
315
- _ -> error $ " Environment not defined for all free vars "
323
+ _ -> Nothing
316
324
317
325
-- | Flatten a CondTree. This will resolve the CondTree by taking all
318
326
-- possible paths into account. Note that since branches represent exclusive
0 commit comments