+useRule :: Rule -> Interval -> ([Interval], [Interval], [Rule])
+useRule (Rule (Iv rl rh) d) (Iv xl xh) = (newResults, newVals, newRules)
+ where newResults =
+ filter legalInterval [ Iv (min xl rl) (min xh (rl - 1)) -- input below rule
+ , Iv ((max xl rl) + d) ((min xh rh) + d)] -- input within rule
+ newVals = filter legalInterval [Iv (max xl (rh + 1)) (max xh rh)] -- input above rule
+ newRules = filter legalRule [Rule (Iv (max (xh + 1) rl) (max xh rh)) d] -- rule above input
+
+useRules :: [Rule] -> [Interval] -> [Interval]
+useRules [] vals = vals
+useRules _ [] = []
+useRules (r@(Rule (Iv rl rh) _):rs) (v@(Iv xl xh):vs)
+ | rh < xl = useRules rs (v:vs)
+ | xh < rl = v : useRules (r:rs) vs
+ | otherwise = newResults ++ (useRules (newRules ++ rs) (newVals ++ vs))
+ where (newResults, newVals, newRules) = useRule r v