Commit 1e636b10 authored by Rinus Plasmeijer's avatar Rinus Plasmeijer

the andCond task has been generalized;

it is renamed, has an additional argument which determines which of the tasks should be displayed.
this is not an itask, but an idata.
this makes it possible to switch dynamically between the tasks to display.

all existing combinators "and" and ""or have been defined in terms of this new basic combinator
parent c375c026
......@@ -31,7 +31,7 @@ return_V :: !a -> Task a | iCreateAndPrint a
Assign tasks to user with indicated id:
assignTaskTo :: assign task to indicated user
*/
assignTaskTo :: !UserId !(LabeledTask a) -> Task a | iData a
assignTaskTo :: !UserId !(LabeledTask a) -> Task a | iData a
/*
Repetition and loops:
......@@ -48,25 +48,26 @@ seqTasks :: do all iTasks one after another, task completed when all done
seqTasks :: ![LabeledTask a] -> Task [a] | iCreateAndPrint a
/*
Select the tasks to do from a given list of tasks:
selectTasks :: the first argument is task yielding the task numbers (index in the list) to do; illegal indices will be ignored
the second argument is a task that should perform these tasks (in any order, sequential or concurrent).
selectTasks :: Select n tasks to do out of m (n <= m) and do them in indicated order (either sequential or interleaved)
*/
selectTasks :: !([LabeledTask a] -> Task [Int]) !(![LabeledTask a] -> Task [a]) ![LabeledTask a] -> Task [a] | iData a
:: SelectingTask a :== [LabeledTask a] -> Task [Int] // task selecting which tasks to do
:: OrderingTask a :== [LabeledTask a] -> Task [a] // task determining in which order the selected tasks are done (can be interleaved or sequential)
selectTasks :: !(SelectingTask a) !(OrderingTask a) ![LabeledTask a] -> Task [a] | iData a
/*
Do m Tasks parallel / interleaved and FINISH as soon as SOME Task completes:
orTask2 :: do both iTasks in any order, combined task completed as any subtask is done
andTask2 :: do both iTasks in any order (interleaved), task completed when both done
andTasksCond :: do tasks in any order until pred holds for finished tasks, string used for naming group of task navigation buttons
Execute all Tasks in parallel / interleaved and FINISH as soon as the predicate holds for the tasks which are finished:
allTasksCond :: - string is used to give a useful name to the trace;
- TaskToShow is some iData based form such that dynamically can be chosen which tasks to show;
- the predicate is applied on the set of tasks which are finished
*/
orTask2 :: !(Task a,Task b) -> Task (EITHER a b)
| iCreateAndPrint a & iCreateAndPrint b
andTask2 :: !(Task a,Task b) -> Task (a,b) | iCreateAndPrint a & iCreateAndPrint b
andTasksCond :: !String !([a] -> Bool) ![LabeledTask a] -> Task [a] | iData a
:: TasksToShow a :== !String ![LabeledTask a] !*TSt *-> *(([Int],HtmlCode),!*TSt) // some iData determining which tasks to show
:: FinishPred a :== ![a] -> Bool
allTasksCond :: !String !(TasksToShow a) !(FinishPred a) ![LabeledTask a] -> Task [a] | iData a
/* Support for user defined combinators
newTask :: same, but optimized: after completion only result will remembered
newTask :: lifts a (user defined) task to an abstract unit: after completion of a (complicated task) only i's final result will be remembered
Once :: task will be done only once, the value of the task will be remembered, important for side effecting functions lifted to iData domain
*/
newTask :: !String !(Task a) -> Task a | iData a
......
......@@ -143,7 +143,7 @@ where
// ******************************************************************************************************
// Select the tasks to do from a list with help of another task for selecting them:
selectTasks :: !([LabeledTask a] -> Task [Int]) !(![LabeledTask a] -> Task [a]) ![LabeledTask a] -> Task [a] | iData a
selectTasks :: !(SelectingTask a) !(OrderingTask a) ![LabeledTask a] -> Task [a] | iData a
selectTasks chooser executer ltasks = newTask "selectTask" selectTasks`
where
selectTasks`
......@@ -153,8 +153,8 @@ where
lengthltask = length ltasks
// ******************************************************************************************************
// Speculative OR-tasks: task ends as soon as one of its subtasks completes
/*
orTask2 :: !(Task a,Task b) -> (Task (EITHER a b)) | iCreateAndPrint a & iCreateAndPrint b
orTask2 (taska,taskb) = mkTask "orTask2" (doorTask2 (taska,taskb))
where
......@@ -179,8 +179,6 @@ where
= (RIGHT b,{tst & html = html, activated = True})
= (LEFT a,{tst & activated = False, html = html +|+ ahtml +|+ bhtml})
// ******************************************************************************************************
// Parallel task ends when all it subtask are ended as well
andTask2 :: !(Task a,Task b) -> (Task (a,b)) | iCreateAndPrint a & iCreateAndPrint b
andTask2 (taska,taskb) = mkTask "andTask2" (doAndTask (taska,taskb))
......@@ -190,8 +188,9 @@ where
# (b,tst=:{activated=bdone,html=bhtml}) = mkParSubTask "andTask" 1 taskb {tst & tasknr = tasknr, html = BT []}
= ((a,b),{tst & activated = adone&&bdone, html = html +|+ ahtml +|+ bhtml})
andTasksCond :: !String !([a] -> Bool) ![LabeledTask a] -> (Task [a]) | iData a // predicate used to test whether tasks are finished
andTasksCond label pred taskCollection = mkTask "andTasksPred" (doandTasks taskCollection)
andTasksCond label pred taskCollection = mkTask "andTasksCond" (doandTasks taskCollection)
where
doandTasks [] tst = return [] tst
doandTasks taskCollection tst=:{tasknr,html,options,userId}
......@@ -234,6 +233,44 @@ where
# (a,tst=:{activated = adone}) = mkParSubTask traceid ctasknr task {tst & tasknr = tasknr, activated = True} // check tasks
| adone = checkAllTasks traceid options (inc ctasknr,skipnr) bool [(taskname,a):alist] {tst & tasknr = tasknr, activated = True}
= checkAllTasks traceid options (inc ctasknr,skipnr) False alist {tst & tasknr = tasknr, activated = True}
*/
allTasksCond :: !String !(TasksToShow a) !(FinishPred a) ![LabeledTask a] -> Task [a] | iData a
allTasksCond label chooser pred taskCollection
= mkTask "andTasksCond" (doandTasks chooser taskCollection)
where
lengthltask = length taskCollection
doandTasks chooser [] tst = return [] tst
doandTasks chooser taskCollection tst=:{tasknr,html,options,userId}
# ((alist,acode),tst=:{activated=finished,html=allhtml})
= checkAllTasks label taskCollection 0 True ([],[]) {tst & html = BT [],activated = True}
| finished = (alist,{tst & html = html}) // stop, all andTasks are finished
| pred alist = (alist,{tst & html = html, activated = True}) // stop, all work done so far satisfies predicate
# selectId = iTaskId userId tasknr "anTaskSelect"
# ((selected,shtml),tst) = chooser selectId taskCollection {tst & html = BT []}
# (_,tst=:{html=ashtml}) = showtasks label [(i,taskCollection!!i) \\ i <- selected | i >= 0 && i < lengthltask] {tst & html = BT [], activated = True}
= (alist,{tst & activated = finished
, html = html +|+ // show previous code
((BT shtml) +-+ ashtml) +|+ // show selection button + selected itasks
(userId -@: foldl (+|+) (BT []) [htmlcode \\ htmlcode <- acode & i <- [0..] | not (isMember i selected)]) // dont show non selected itasks, but scan them for task tree info
})
where
showtasks :: !String ![(!Int,!LabeledTask a)] !*TSt -> *(![a],!*TSt) | iCreateAndPrint a
showtasks _ [] tst = ([],tst)
showtasks label [(chosen,(name,chosenTask)):tasks] tst=:{html=html}
# (a,tst=:{html=ahtml}) = mkParSubTask label chosen chosenTask {tst & tasknr = tasknr, activated = True, html = BT []}
# (as,tst=:{html=ashtml}) = showtasks label tasks {tst & html = BT []}
= ([a:as],{tst & html = html +|+ ahtml +|+ ashtml})
checkAllTasks :: !String ![LabeledTask a] !Int !Bool !(![a],![HtmlTree]) !*TSt -> *(!(![a],![HtmlTree]),!*TSt) | iCreateAndPrint a
checkAllTasks traceid taskCollection ctasknr bool (alist,acode) tst=:{tasknr}
| ctasknr == length taskCollection = ((reverse alist,reverse acode),{tst & activated = bool}) // all tasks tested
# (taskname,task) = taskCollection!!ctasknr
# (a,tst=:{activated = adone,html=html})
= mkParSubTask traceid ctasknr task {tst & tasknr = tasknr, activated = True, html = BT []} // check tasks
| adone = checkAllTasks traceid taskCollection (inc ctasknr) bool ([a:alist],[html:acode]) {tst & tasknr = tasknr, activated = True}
= checkAllTasks traceid taskCollection (inc ctasknr) False (alist,[html:acode]) {tst & tasknr = tasknr, activated = True}
// ******************************************************************************************************
// Higher order tasks ! Experimental
......
......@@ -89,14 +89,21 @@ mchoiceAndTasks3 :: !HtmlCode ![((!Bool,!ChoiceUpdate,!HtmlCode),LabeledTask a)]
(-||-) :: do both iTasks in any order, combined task completed as soon as any subtask is done
(-&&-) :: do both iTasks in any order (interleaved), task completed when both done
orTasks :: do all iTasks in any order (interleaved), task completed as soon as any subtask is done
orTask2 :: do both iTasks in any order, combined task completed as any subtask is done
andTasks :: do all iTasks in any order (interleaved), task completed when all done
andTask2 :: do both iTasks in any order (interleaved), task completed when both done
andTasks_mu :: assign task to indicated users, task completed when all done
andTasksCond :: do all iTasks in any order (interleaved), task completed when predicate holds for finished tasks
*/
(-||-) infixr 3 :: !(Task a) !(Task a) -> Task a | iData a
(-&&-) infixr 4 :: !(Task a) !(Task b) -> Task (a,b) | iData a & iData b
orTasks :: ![LabeledTask a] -> (Task a) | iData a
orTask2 :: !(Task a,Task b) -> Task (EITHER a b)
| iData a & iData b
andTasks :: ![LabeledTask a] -> Task [a] | iData a
andTask2 :: !(Task a,Task b) -> Task (a,b) | iData a & iData b
andTasks_mu :: !String ![(Int,Task a)] -> Task [a] | iData a
andTasksCond :: !String !([a] -> Bool) ![LabeledTask a] -> (Task [a]) | iData a
/* convenient combinators for tasks that maybe return a result:
(=>>?) :: as bind, but do the second task only if the first one delivers a result
......
......@@ -109,7 +109,6 @@ where
= ([chosen.value],{tst & activated = True})
= ([chosen.value],{tst & activated = True})
chooseTask_pdm :: !HtmlCode !Int ![LabeledTask a] -> Task a | iData a
chooseTask_pdm prompt initial ltasks
= selectTasks (\lt -> prompt ?>> selectTask_pdm initial lt) seqTasks ltasks =>> \la -> return_V (hd la)
......@@ -237,7 +236,7 @@ mchoiceAndTasks3 prompt taskOptions
(-||-) infixr 3 :: !(Task a) !(Task a) -> (Task a) | iData a
(-||-) taska taskb = newTask "-||-" (doOrTask (taska,taskb))
where
doOrTask :: !(Task a,Task a) -> (Task a) | iCreateAndPrint a
doOrTask :: !(Task a,Task a) -> (Task a) | iData a
doOrTask (taska,taskb)
= orTask2 (taska,taskb)
=>> \at -> case at of
......@@ -252,6 +251,15 @@ orTasks [] = return createDefault
orTasks taskCollection = newTask "orTasks" (andTasksCond "or Tasks" (\list -> length list >= 1) taskCollection)
=>> \list -> return (hd list)
orTask2 :: !(Task a,Task b) -> Task (EITHER a b) | iData a & iData b
orTask2 (taska,taskb)
= allTasksCond "orTask2" showBoth (\list -> length list > 0) [("orTask.0",taska =>> \a -> return_V (LEFT a)),("orTask.0",taskb =>> \b -> return_V (RIGHT b))]
=>> \res -> return_V (hd res)
showBoth id list tst=:{hst}
# (sel,hst) = mkEditForm (Init,nFormId id [0,1] <@ NoForm) hst
= ((sel.value,sel.form),{tst & hst = hst})
andTasks :: ![LabeledTask a] -> (Task [a]) | iData a
andTasks taskCollection = newTask "andTasks" (andTasksCond "and Tasks" (\_ -> False) taskCollection)
......@@ -271,11 +279,28 @@ where
noNothing [RIGHT Nothing:xs] = True
noNothing [x:xs] = noNothing xs
andTask2 :: !(Task a,Task b) -> Task (a,b) | iData a & iData b
andTask2 (taska,taskb)
= allTasksCond "andTask2" showBoth (\l -> False) [("andTask.0",taska =>> \a -> return_V (LEFT a)),("andTask.0",taskb =>> \b -> return_V (RIGHT b))]
=>> \[LEFT a, RIGHT b] -> return_V (a,b)
andTasks_mu :: !String ![(Int,Task a)] -> (Task [a]) | iData a
andTasks_mu label tasks = newTask "andTasks_mu" (domu_andTasks tasks)
where
domu_andTasks list = andTasks [(label <+++ " " <+++ i, i @:: task) \\ (i,task) <- list]
andTasksCond :: !String !([a] -> Bool) ![LabeledTask a] -> (Task [a]) | iData a
andTasksCond label pred taskCollection
= allTasksCond label selectButtons pred taskCollection
where
selectButtons id list tst=:{hst,userId,tasknr,options}
# ((i,buttons,chosenname),hst) = mkTaskButtons True "mybut" userId tasknr options (map fst list) hst
= (([i],mkbuttons buttons chosenname),{tst & hst = hst})
where
mkbuttons buttons chosenname = if (length list > 1)
[showMainLabel "and",showTrace " / ",showLabel chosenname: buttons]
[]
// ******************************************************************************************************
// Timer Tasks ending when timed out
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment