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())
andFunTy(FloatTy(), FloatTy())
.- Task 2 rewrites task 1 to the first subterm. It has two results,
IntTy()
andFloatTy()
.- Task 3 rewrites task 1 to the second subterm. It has two results,
IntTy()
andFloatTy()
.- 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 awhere
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
andtask-create-filter
areResult -> Result
. This will work fine if the sourceResult
will get replaced by a single element. If however the sourceResult
is in fact a list of terms then the task<check> result
will succeed if it succeeds forat 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 be single result or multiple results. 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