/** * This module contains strategies for filtering and partitioning * lists. */ module collection/list/filter imports collection/list/- strategies /** * Returns all elements in a list that satisfy s, as a list. * * @param s a -> b * @type List(a) -> List(b) * * @inc test1 */ filter(s) = [] + [s | filter(s)] <+ ?[_ | <filter(s)> ] filter(s, tail) = ?[]; tail <+ [s | filter(s, tail)] <+ ?[_ | <filter(s, tail)> ] strategies /** * Returns all elements in a list that satisfy s, as a list. * * @param s a -> b * @type List(a) -> List(b) */ retain-all(s) = filter(s) /** * Removes all elements from a list that satisfy s * * @param s a -> b * @type List(a) -> List(a) */ remove-all(s) = filter(not(s)) strategies /** * Returns all elements in a list that satisfy s, as a list. * Traverses the list in reverse order. * * @param s a -> b * @type List(a) -> List(b) */ reverse-filter(s) = [] + [id | reverse-filter(s)]; ([s | id] <+ ?[_ | <id>]) reverse-filter(s, tail) = ?[]; tail + ?[x | xs] ; <reverse-filter(s, tail)> xs ; try(![<s> x | <id>]) /** @internal */ filter-gen(pred, cont : (term -> term) * term -> term) = rec x([] + (pred; cont(x)) <+ Tl; x) /** @internal */ filter-option-args(flag) = let skip(s) = at-tail(s) in filter-gen([flag | id]; Tl, skip) end /** @internal */ filter-options(flag) = let skip(s) = at-tail(at-tail(s)) in filter-gen([flag | id], skip) end /** @internal */ list-some-filter(s) = rec x([s| id]; [id| filter(s)] <+ [id| x]; Tl) /** * Partitions a list into a tuple of two lists. * * The argument s is applied to all elements of the list. The * results of the succesful applications are returned in the first * list. The terms to which s cannot be applied are returned in the * second list. * * @param s a -> b * @type List(a) -> (List(b), List(a)) * * @inc test2 */ partition(s) = partition(s, id) /** * Partitions a list into a tuple of two lists. * * @param s1 a -> b * @param s2 a -> c * @type List(a) -> (List(b), List(c)) */ partition(s1, s2) = rec part( \ [] -> ([],[]) \ + ({[s1 => x | id]; ?[_|<part>]; !([x | <Fst>], <Snd>)} <+ {[s2 => x | id]; ?[_|<part>]; !(<Fst>, [x | <Snd>])}) ) /** @internal */ partition'(s) = rec part( \ [] -> ([],[]) \ + \ [z | zs] -> <!([<s> z | xs], ys) <+ !(xs, [z | ys])> where <part> zs => (xs, ys) \ )