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
filtertask. I’ve implemented awheretask (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 -> InstructionIts 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
checkandtask-create-filterareResult -> Result. This will work fine if the sourceResultwill get replaced by a single element. If however the sourceResultis in fact a list of terms then the task<check> resultwill succeed if it succeeds forat least oneof 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())> statusThe question is whether the
check-choicewill 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