## Filter multiple results of tasks

In the current setup, a task which depends on another task with multiple results is executed on each of these results and might produce multiple results as well.

There are cases where you want to restrict the results of a task by applying another task to it. Here is an example:

- Task 1 calculates the type of an overloaded operator. The task has two results
`FunTy(IntTy(), IntTy())`

and`FunTy(FloatTy(), FloatTy())`

.- Task 2 rewrites task 1 to the first subterm. It has two results,
`IntTy()`

and`FloatTy()`

.- Task 3 rewrites task 1 to the second subterm. It has two results,
`IntTy()`

and`FloatTy()`

.- Task 4 calculated the type of a subexpression. It has a single result
`IntTy()`

.- Task 5 matches task 2 with task 4. It succeeds on the first result of task 2, and fails on the second result. Thus, it has a single result
`IntTy()`

.The expression should have type

`IntTy()`

. However, there is no way to express this currently. Conceptually, task 3 has the result, but it should give only the first result, since task 5 only works on the first result of task 1.In resolution tasks, this filtering is hardcoded into the task execution. A conceptual solution to this on task level would supersede this.

Submitted by Guido Wachsmuth on 10 December 2013 at 18:14

## Issue Log

I don’t entirely understand the example in the description.

I’ve also repeatedly run into the lack of a

`filter`

task. I’ve implemented a`where`

task (https://github.com/metaborg/runtime-libraries/commit/9a7e5bb07ca353348aa26f4c56e8755cc6a7153a) but it does not work for filtering over lists.Let’s try to formalise this a bit. What we want is to have a task:

`Filter: Result * Check -> Instruction`

Its naive task creation factory will look like this:

`task-create-filter(check|ctx) = ?result; <new-task(|ctx)> Filter(result, <check> result)`

The evaluation:

`perform-task(|n) = ?Filter(<id>, [_|_])`

Where

`check`

and`task-create-filter`

are`Result -> Result`

. This will work fine if the source`Result`

will get replaced by a single element. If however the source`Result`

is in fact alistof terms then the task`<check> result`

will succeed if it succeeds for`at least one`

of these terms.Would this maybe work:

`signature constructors Zip: Result * Result -> Instruction Where: Result -> Instruction TASKFAILURE: Term rules task-create-zip(|ctx): (result1, result2) -> <new-task(|ctx)> Zip(result1, result2) task-is-combinator = ?Zip(_, _) perform-task(|n): Zip(r1, r2) -> <zip(id)> (r1, r2) task-create-where(check|ctx): result -> <new-task(|ctx)> Where(result-and-status) where check-choice := <task-create-choice(|ctx)> [<check> result, TASKFAILURE()]; result-and-status := <new-task(|ctx)> Zip(result, check-choice) perform-task(|n): Where((r1, status)) -> r1 where <not(?TASKFAILURE())> status`

The question is whether the

`check-choice`

will besingleresult ormultipleresults. That and whether it’s allowed to have a non-result (i.e. actual term) in the alternative of the choice.

*Log in to post comments*