r-io suiter-io suitededuction docs
← All strategies
Deduction / Shared mechanism

Conditioned Implies, Supports and Needs links

A link between two functions can carry a 2L Condition Evaluation: the dependent task is only executed when the condition holds at runtime. The deduction never decides the condition, since it usually reads the output of a task that has not run yet. Instead, it copies the condition onto the process flows, adds the flows that skip the task, and plans sibling tasks according to whether their conditions are exclusive or inclusive.

implemented byFunctionLinkConditions · Scheduler · ResourceAssigner
The condition is evaluated when the process runs

In the IMT Albi Crisis use case, Confirm gas leak implies Cut off the local gas valve when @Confirmed gas leak[Confirm gas leak] == "Yes and repairable" and Cut off the school gas supply when it equals "Yes and non-repairable". The answer is only known once the firefighter has confirmed the leak, so the deduced process keeps both branches and the engine follows the right one.

00 · At a glance

What goes in, what is decided, what comes out

Inputs

From the collaborative model

  • Implies, Supports and Needs edges between functions, with their Condition Evaluation property (2L code editor, hidden on the diagram, shown as a CE badge).
  • The quick access @variable[Function name] reads an output variable of the task of that function.
Decisions

Taken at deduction

  • The guard of each task: the logical AND of the conditions of its links.
  • Whether sibling guards are exclusive (never both true) or inclusive (possibly both true).
  • The actors and the order of the sibling tasks.
Outputs

In the deduced process

  • Conditioned Sequence_Flows entering each guarded task.
  • otherwise flows to the End_Event, which release the objectives of the skipped tasks.
  • bypass flows when the planning placed a guarded task after a sibling that may be skipped.
01 · Guard of a task

Which condition guards which task

A condition always guards the dependent task, whatever the direction of the edge.

LinkGuarded taskPlanning
A Implies BBB after A
A Supports BBB in parallel with A (support task)
B Needs ABB after A

Copied onto every entering flow — the planning may insert other tasks before B, so the guard of B is copied onto every Sequence_Flow entering B. The quick access names the function explicitly, so the condition does not depend on the flow carrying it. Several conditions guarding the same task are combined with a logical AND, their local variables being renamed so that they do not collide.

One otherwise flow per source and condition — the process must not stay blocked before B when the guard is false: a flow X → End_Event named otherwise carries the negated guard (id <conditioned flow id>__otherwise). Conditioned flows leaving the same node with the same condition, written differently or not, share one otherwise flow.

Objectives released — following an otherwise flow skips B and the tasks only reachable through B. Their objectives will never be reached by a task completion, so the flow lists them in its releasesObjectives property and the engine releases their EXPECTED_FREEZE twin.

Pseudo-codecopyOnSequenceFlows
for flow X -> T in process.sequenceFlows:
  guard = AND(conditions of the links guarding T)
  if guard is empty: continue
  flow.condition = guard
  key = (X, canonical(guard))              # one otherwise per key
  otherwise[key] = X -> End_Event
      condition = NOT guard
      releasesObjectives += objectives of T
                            and of the tasks only reachable through T
02 · Exclusive or inclusive

How sibling conditions are compared

Sibling tasks depend on the same task through conditioned links (A Implies B and A Implies C, or B Needs A and C Needs A). Their guards are compared term by term, the terms being those of their logical AND.

RelationDetected when two terms areAt runtimePlanning
Exclusivethe same expression compared with == to two different literals · compared with == and != to the same literal · an expression and its negation !at most one of the tasks runsnever ordered against each other, may share actors and resources
Inclusiveany other case, same or different conditionsboth, one or none of the tasks runoptional support tasks: in parallel when possible, in sequence otherwise

The literal may be on either side of the comparison, and a condition written boolean ok = <expression>; ok; is analysed through the initial value of its local variables. A term that still depends on the statements of the condition cannot be compared and is considered compatible.

Two conditions are the same when their canonical writing is identical: the 2L code is parsed and printed again, so spaces, line breaks and a missing trailing ; do not matter.

ExamplesareExclusiveConditions
@x[F] == "a"          vs  @x[F] == "b"      # exclusive
@x[F] == "a"          vs  @x[F] != "a"      # exclusive
@ok[F]                vs  !@ok[F]           # exclusive
@x[F] == "a" && @n[F] > 3  vs  @x[F] == "b" # exclusive
@x[F] == "a"          vs  @y[F] == "b"      # inclusive
@n[F] > 3             vs  @n[F] < 2         # inclusive (not detected)
@x[F] == "a" || @y[F] vs  @x[F] == "b"      # inclusive
03 · Exclusive

Both branches follow their common task

The scheduler used to place a task after its sibling as soon as they shared an actor or a resource. With exclusive guards this made the second branch unreachable: to reach it, the process had to go through the first one, whose condition is its opposite.

Scheduler — each scheduled task knows the ids of the tasks exclusive with it (ScheduleTask.exclusiveTaskIds). The time slots they reserved never make it unavailable, so every exclusive branch starts right after the common task, each with its own condition. Nor is a task ever chained after an exclusive one: it would only be reached in the other branch.

Actors of support tasks — support tasks of the same task normally need distinct actors. Exclusive support tasks never run together, so they may share one (ResourceTask.exclusiveFunctionIds).

Inherited by descendants — a function is guarded by its own links and by the guards of the functions it depends on (Implies, Supports, Needs): with “B Implies D”, D is exclusive with C as B is. A function depending on several functions keeps only the conditions they all share, since any of them may lead to it.

Moves — a move inserted by the move improver (“Move to <task>”, whose only flow goes to that task) stands for its task: same guard, same prerequisites, skipped with it. The condition is carried by the flow entering the move, not by the flow from the move to its task.

IMT Albi Crisisdeduced process
Start -> Confirm gas leak
Confirm gas leak -> Cut off the local gas valve
    [@Confirmed gas leak[Confirm gas leak] == "Yes and repairable"]
Confirm gas leak -> Cut off the school gas supply
    [@Confirmed gas leak[Confirm gas leak] == "Yes and non-repairable"]
Confirm gas leak -> End   # otherwise, one per branch
04 · Inclusive

Optional support tasks and bypass flows

With two inclusive conditions C1 (task B) and C2 (task C), four outcomes must stay possible: C1 and C2, C1 only, C2 only, none.

Optional support tasks — inclusive siblings prefer different actors: the actors already assigned to a sibling are offered last (ResourceAssigner.prioritizeActorsFreeOfInclusiveTasks). When another actor is available the tasks run in parallel. Otherwise the same actor is kept and the scheduler places them in sequence; the solution is not lost.

Bypass flows — when the planning placed C after B, although B is not a prerequisite of C, and B may be skipped while C is not (a condition of B does not guard C), C would become unreachable when B is skipped. For each flow P → B, a flow P → C named bypass (id <P id>__bypass__<C id>) carries guard(C) AND NOT guard(B). Its own otherwise flow (id ending with __skipped__otherwise) carries NOT guard(B) AND NOT guard(C) and releases the objectives of C. Longer chains are bypassed recursively. No bypass is added when the two guards are the same: C then runs exactly when B runs.

OutcomeFollowed flows
C1 and C2A → B, then B → C
C1 onlyA → B, then B → End (otherwise of C, releases C)
C2 onlyA → End (otherwise of B, releases B) and A → C (bypass)
noneA → End (otherwise of B) and A → End (skipped otherwise, releases C)
A B C End C1 C2 bypass: C2 and not C1 otherwise: not C1 · skipped: not C1 and not C2 otherwise: not C2
C was placed after B because they share an actor; the bypass keeps C reachable when B is skipped.
05 · Waiting

Waiting is a function, not a link

A link condition is always a branch, read once when the source task ends. To hold a task until a situation changes (a flood to recede before a bridge is inspected), the model places a Mediation function with the operation Wait Until between the two functions, linked by plain Implies links.

The wait function — it carries a 2L Wait Condition ($source = the wait task, $target = the task it leads to), a Wait Polling (s) (5 by default) and a Function:duration given as a range, for instance 6 to 24 h. It needs no actor; the deduced task is a Mediation task that copies the condition and the polling (WaitTasks).

Planning — a range duration is planned with its minimum, which gives the earliest dates. Every task after the wait gets an expected latest end date on its Plans edge, its planned end plus the width of the range: it is planned in a window. The deadline of an objective does not apply to the tasks after a wait.

At run time — the engine evaluates the condition every Wait Polling (s) (WaitUntilSkill) and ends the wait as soon as it is true; a condition that cannot be evaluated yet keeps waiting. Only that branch waits. The wait stops without completing when the process ends, and it is not observed in simulation. In r-iota a task after a wait is late only after its latest end.

Orléans Flood Crisisdeduced process
Close a bridge to traffic
  -> Wait until a bridge can be inspected
       [Wait Condition: the flood is over
        and the risk is below 0.8]      # every 5 s
       # duration 6 to 24 h
  -> Inspect a bridge after a flood
       # planned from the earliest end of the wait,
       # latest end 18 h later

The conditions of the wait functions are written in the 2L language reference.

06 · Runtime

What the workflow engine does

LEAVEEvaluate the conditioned flowsinclusiveWhen a task ends, every outgoing flow whose condition is true is followed, together with the unconditioned ones (PRIOTransitionController, SequenceFlowConditionEvaluator). A condition that fails to evaluate counts as false.
PAIROtherwise = negationby idAn otherwise flow is not evaluated on its own: its result is the negation of its conditioned flow, found by removing the __otherwise suffix, so exactly one of both is followed. A skipped otherwise has no conditioned flow of that id and is evaluated on its own condition.
RELEASESkipped objectivesasyncAn objective is reached when its whole task graph is finished: the task satisfying it and the tasks it requires (Needs, Implies, Supports, conditioned or not), each one done or skipped by a false condition. The engine records the tasks the dead flows skip (ObjectiveTaskGraph); a task still reachable by another flow, such as a bypass, is not skipped. The r-io suite web application then releases the EXPECTED_FREEZE twin of the objectives whose graph is finished, including when the process ends. Recovery tasks entered only by an Exception_Flow or Event_Flow are not part of the graph. Without that listener, the engine falls back to the objectives listed in releasesObjectives of the otherwise flow (OtherwiseFlowObjectiveRelease).
JOINDead paths are not awaitedreverse pathA task with several entering flows does not wait for a flow whose upstream path is dead: C starts once, from B or from the bypass. The End_Event waits for every live path.
07 · Watch points

What to keep in mind

Detection on the writing only

Exclusivity is detected on the syntax of the conditions: @n[F] > 3 and @n[F] < 2 are exclusive but treated as inclusive. The result stays correct, since bypass flows keep every outcome reachable, but the plan may be longer than necessary. A real expression solver is planned.

Quote the text values

@x[F] == Yes and non-repairable is a syntax error: the condition cannot be evaluated, the flow is never followed and its otherwise flow always is. Write "Yes and non-repairable", exactly as the value of the output variable.

Extra flows in the process

The otherwise, bypass and skipped otherwise flows are plain model edges added when the process model is built. Their ids are deterministic: the same process always gives the same flows.

Inclusive tasks and actors

A different actor is only preferred, never required: with a single actor of the role, inclusive tasks are planned in sequence with bypass flows.

08 · Sources

Where to read further

gind-governance-workflow-deduction-strategy-abstract/…/process/edges/FunctionLinkConditions.javaGuards, combination and negation, exclusive and inclusive functions, otherwise and bypass flows.
gind-governance-workflow-planner-default/…/scheduler/Scheduler.java · ScheduleProcess.javaExclusive tasks never block each other.
gind-governance-workflow-planner-default/…/resources/ResourceTaskGraph.java · ResourceAssigner.javaExclusive and inclusive functions of the task graph, actor preference of inclusive tasks.
gind-workflow-engine-prio/…/boundary/SequenceFlowConditionEvaluator.java · OtherwiseFlowObjectiveRelease.javaRuntime evaluation and release of the skipped objectives.
…/process/nodes/WaitTasks.java · gind-workflow-engine-prio/…/skill/mediation/WaitUntilSkill.javaWait functions (Mediation, Wait Until): no actor, copied condition and polling, waiting at run time.
gind-models-collaborative-model/…/Collaborative_MetaModel.xmlCondition Evaluation of Implies, Supports, Needs and Sequence_Flow; Wait Condition and Wait Polling (s) of the functions and tasks.
Déduction / Mécanisme commun

Liens Implies, Supports et Needs conditionnés

Un lien entre deux fonctions peut porter une Condition Evaluation 2L : la tâche dépendante ne s’exécute que si la condition est vraie à l’exécution. La déduction ne tranche jamais la condition, qui lit en général la sortie d’une tâche pas encore exécutée. Elle recopie la condition sur les flux du processus, ajoute les flux qui sautent la tâche et planifie les tâches sœurs selon que leurs conditions sont exclusives ou inclusives.

implémenté parFunctionLinkConditions · Scheduler · ResourceAssigner
La condition est évaluée à l’exécution du processus

Dans le cas d’usage IMT Albi Crisis, Confirm gas leak implique Cut off the local gas valve quand @Confirmed gas leak[Confirm gas leak] == "Yes and repairable" et Cut off the school gas supply quand la valeur vaut "Yes and non-repairable". La réponse n’est connue qu’une fois la fuite confirmée par le pompier : le processus déduit garde les deux branches et le moteur suit la bonne.

00 · En bref

Ce qui entre, ce qui est décidé, ce qui sort

Entrées

Depuis le modèle collaboratif

  • Les arêtes Implies, Supports et Needs entre fonctions, avec leur propriété Condition Evaluation (éditeur de code 2L, masquée sur le diagramme, signalée par un badge CE).
  • L’accès rapide @variable[Nom de la fonction] lit une variable de sortie de la tâche de cette fonction.
Décisions

Prises à la déduction

  • La garde de chaque tâche : le ET logique des conditions de ses liens.
  • Si les gardes de tâches sœurs sont exclusives (jamais vraies ensemble) ou inclusives (possiblement vraies ensemble).
  • Les acteurs et l’ordre des tâches sœurs.
Sorties

Dans le processus déduit

  • Des Sequence_Flow conditionnés entrant dans chaque tâche gardée.
  • Des flux otherwise vers l’End_Event, qui libèrent les objectifs des tâches sautées.
  • Des flux bypass quand la planification a placé une tâche gardée après une tâche sœur qui peut être sautée.
01 · Garde d’une tâche

Quelle condition garde quelle tâche

Une condition garde toujours la tâche dépendante, quel que soit le sens de l’arête.

LienTâche gardéePlanification
A Implies BBB après A
A Supports BBB en parallèle de A (tâche support)
B Needs ABB après A

Recopiée sur chaque flux entrant — la planification peut insérer d’autres tâches avant B : la garde de B est donc recopiée sur chaque Sequence_Flow entrant dans B. L’accès rapide nomme explicitement la fonction, la condition ne dépend donc pas du flux qui la porte. Plusieurs conditions gardant la même tâche sont combinées par un ET logique, leurs variables locales étant renommées pour ne pas entrer en collision.

Un flux otherwise par source et par condition — le processus ne doit pas rester bloqué avant B quand la garde est fausse : un flux X → End_Event nommé otherwise porte la garde niée (id <id du flux conditionné>__otherwise). Les flux conditionnés qui quittent le même nœud avec la même condition, écrite de la même façon ou non, partagent un seul flux otherwise.

Objectifs libérés — suivre un flux otherwise saute B et les tâches atteignables seulement par B. Leurs objectifs ne seront jamais atteints par la fin d’une tâche : le flux les liste dans sa propriété releasesObjectives et le moteur libère leur jumeau EXPECTED_FREEZE.

Pseudo-codecopyOnSequenceFlows
pour chaque flux X -> T du processus :
  garde = ET(conditions des liens gardant T)
  si garde vide : continuer
  flux.condition = garde
  cle = (X, canonique(garde))             # un otherwise par clé
  otherwise[cle] = X -> End_Event
      condition = NON garde
      releasesObjectives += objectifs de T
                            et des tâches atteignables seulement par T
02 · Exclusif ou inclusif

Comment les conditions sœurs sont comparées

Des tâches sœurs dépendent de la même tâche par des liens conditionnés (A Implies B et A Implies C, ou B Needs A et C Needs A). Leurs gardes sont comparées terme à terme, les termes étant ceux de leur ET logique.

RelationDétectée quand deux termes sontÀ l’exécutionPlanification
Exclusivela même expression comparée par == à deux littéraux différents · comparée par == et != au même littéral · une expression et sa négation !au plus une des tâches s’exécutejamais ordonnées l’une par rapport à l’autre, peuvent partager acteurs et ressources
Inclusivetous les autres cas, conditions identiques ou différentesles deux, une seule ou aucune des tâches s’exécutenttâches supports optionnelles : en parallèle si possible, sinon en séquence

Le littéral peut être de part ou d’autre de la comparaison, et une condition écrite boolean ok = <expression>; ok; est analysée à travers la valeur initiale de ses variables locales. Un terme qui dépend encore des instructions de la condition ne peut pas être comparé : il est considéré comme compatible.

Deux conditions sont identiques quand leur écriture canonique est la même : le code 2L est analysé puis réimprimé, les espaces, retours à la ligne et un ; final manquant ne comptent donc pas.

ExemplesareExclusiveConditions
@x[F] == "a"          vs  @x[F] == "b"      # exclusives
@x[F] == "a"          vs  @x[F] != "a"      # exclusives
@ok[F]                vs  !@ok[F]           # exclusives
@x[F] == "a" && @n[F] > 3  vs  @x[F] == "b" # exclusives
@x[F] == "a"          vs  @y[F] == "b"      # inclusives
@n[F] > 3             vs  @n[F] < 2         # inclusives (non détecté)
@x[F] == "a" || @y[F] vs  @x[F] == "b"      # inclusives
03 · Exclusif

Les deux branches suivent leur tâche commune

Le planificateur plaçait une tâche après sa sœur dès qu’elles partageaient un acteur ou une ressource. Avec des gardes exclusives, la seconde branche devenait inatteignable : pour l’atteindre, il fallait passer par la première, dont la condition est son contraire.

Ordonnanceur — chaque tâche ordonnancée connaît les ids des tâches exclusives avec elle (ScheduleTask.exclusiveTaskIds). Les créneaux qu’elles ont réservés ne la rendent jamais indisponible : chaque branche exclusive démarre juste après la tâche commune, avec sa propre condition. Une tâche n’est jamais non plus enchaînée après une tâche exclusive : elle ne serait atteinte que dans l’autre branche.

Acteurs des tâches supports — les tâches supports d’une même tâche exigent normalement des acteurs distincts. Des tâches supports exclusives ne s’exécutent jamais ensemble et peuvent donc en partager un (ResourceTask.exclusiveFunctionIds).

Héritée par les descendants — une fonction est gardée par ses propres liens et par les gardes des fonctions dont elle dépend (Implies, Supports, Needs) : avec « B Implies D », D est exclusive avec C comme B. Une fonction qui dépend de plusieurs fonctions ne garde que les conditions qu’elles ont toutes en commun, puisque chacune peut y mener.

Déplacements — un déplacement inséré par l’améliorateur de déplacements (« Move to <tâche> », dont le seul flux mène à cette tâche) représente sa tâche : même garde, mêmes prérequis, sauté avec elle. La condition est portée par le flux qui entre dans le déplacement, pas par celui qui va du déplacement à sa tâche.

IMT Albi Crisisprocessus déduit
Start -> Confirm gas leak
Confirm gas leak -> Cut off the local gas valve
    [@Confirmed gas leak[Confirm gas leak] == "Yes and repairable"]
Confirm gas leak -> Cut off the school gas supply
    [@Confirmed gas leak[Confirm gas leak] == "Yes and non-repairable"]
Confirm gas leak -> End   # otherwise, un par branche
04 · Inclusif

Tâches supports optionnelles et flux bypass

Avec deux conditions inclusives C1 (tâche B) et C2 (tâche C), quatre sorties doivent rester possibles : C1 et C2, C1 seule, C2 seule, aucune.

Tâches supports optionnelles — les tâches sœurs inclusives préfèrent des acteurs différents : les acteurs déjà affectés à une sœur sont proposés en dernier (ResourceAssigner.prioritizeActorsFreeOfInclusiveTasks). Si un autre acteur est disponible, les tâches s’exécutent en parallèle. Sinon le même acteur est gardé et l’ordonnanceur les place en séquence : la solution n’est pas perdue.

Flux bypass — quand la planification a placé C après B alors que B n’est pas un prérequis de C, et que B peut être sautée sans que C le soit (une condition de B ne garde pas C), C deviendrait inatteignable quand B est sautée. Pour chaque flux P → B, un flux P → C nommé bypass (id <id de P>__bypass__<id de C>) porte garde(C) ET NON garde(B). Son propre flux otherwise (id terminé par __skipped__otherwise) porte NON garde(B) ET NON garde(C) et libère les objectifs de C. Les chaînes plus longues sont contournées récursivement. Aucun bypass n’est ajouté quand les deux gardes sont identiques : C s’exécute alors exactement quand B s’exécute.

SortieFlux suivis
C1 et C2A → B, puis B → C
C1 seuleA → B, puis B → End (otherwise de C, libère C)
C2 seuleA → End (otherwise de B, libère B) et A → C (bypass)
aucuneA → End (otherwise de B) et A → End (otherwise « skipped », libère C)
A B C End C1 C2 bypass : C2 et non C1 otherwise : non C1 · skipped : non C1 et non C2 otherwise : non C2
C a été placée après B parce qu’elles partagent un acteur ; le bypass garde C atteignable quand B est sautée.
05 · Attendre

Attendre est une fonction, pas un lien

Une condition de lien est toujours un aiguillage, lu une fois à la fin de la tâche source. Pour retenir une tâche jusqu’à ce qu’une situation change (une crue qui doit refluer avant d’inspecter un pont), le modèle place une fonction Mediation d’opération Wait Until entre les deux fonctions, reliées par de simples liens Implies.

La fonction d’attente — elle porte une Wait Condition 2L ($source = la tâche d’attente, $target = la tâche à laquelle elle mène), un Wait Polling (s) (5 par défaut) et une Function:duration donnée par un intervalle, par exemple 6 à 24 h. Elle n’a besoin d’aucun acteur ; la tâche déduite est une tâche Mediation qui recopie la condition et la scrutation (WaitTasks).

Planification — une durée en intervalle est planifiée avec son minimum, ce qui donne les dates au plus tôt. Chaque tâche qui suit l’attente reçoit une expected latest end date sur son arête Plans, sa fin planifiée plus la largeur de l’intervalle : elle est planifiée dans une fenêtre. L’échéance d’un objectif ne s’applique pas aux tâches qui suivent une attente.

À l’exécution — le moteur évalue la condition toutes les Wait Polling (s) (WaitUntilSkill) et termine l’attente dès qu’elle est vraie ; une condition pas encore évaluable continue d’attendre. Seule cette branche attend. L’attente s’arrête sans se terminer quand le processus finit, et elle n’est pas observée en simulation. Dans r-iota, une tâche qui suit une attente n’est en retard qu’après sa fin au plus tard.

Orléans Flood Crisisprocessus déduit
Close a bridge to traffic
  -> Wait until a bridge can be inspected
       [Wait Condition : la crue est terminée
        et le risque est sous 0,8]       # toutes les 5 s
       # durée 6 à 24 h
  -> Inspect a bridge after a flood
       # planifiée depuis la fin au plus tôt de l’attente,
       # fin au plus tard 18 h plus tard

Les conditions des fonctions d’attente sont écrites dans la référence du langage 2L.

06 · Exécution

Ce que fait le moteur de workflow

SORTIEÉvaluer les flux conditionnésinclusifÀ la fin d’une tâche, chaque flux sortant dont la condition est vraie est suivi, avec les flux non conditionnés (PRIOTransitionController, SequenceFlowConditionEvaluator). Une condition dont l’évaluation échoue compte comme fausse.
PAIREOtherwise = négationpar idUn flux otherwise n’est pas évalué seul : son résultat est la négation de son flux conditionné, retrouvé en retirant le suffixe __otherwise, donc exactement un des deux est suivi. Un otherwise « skipped » n’a pas de flux conditionné de cet id et est évalué sur sa propre condition.
LIBÉRERObjectifs sautésasyncUn objectif est atteint quand tout son graphe de tâches est terminé : la tâche qui le satisfait et celles qu’il requiert (Needs, Implies, Supports, conditionnées ou non), chacune faite ou sautée par une condition fausse. Le moteur enregistre les tâches sautées par les flux morts (ObjectiveTaskGraph) ; une tâche encore atteignable par un autre flux, comme un bypass, n’est pas sautée. L’application web de r-io suite libère alors le jumeau EXPECTED_FREEZE des objectifs dont le graphe est terminé, y compris à la fin du processus. Les tâches de reprise entrées seulement par un Exception_Flow ou un Event_Flow ne font pas partie du graphe. Sans cet écouteur, le moteur se rabat sur les objectifs listés dans releasesObjectives du flux otherwise (OtherwiseFlowObjectiveRelease).
JOINTURELes chemins morts ne sont pas attenduschemin inverseUne tâche à plusieurs flux entrants n’attend pas un flux dont le chemin amont est mort : C démarre une seule fois, depuis B ou depuis le bypass. L’End_Event attend tous les chemins vivants.
07 · Points de vigilance

À garder en tête

Détection sur l’écriture seulement

L’exclusivité est détectée sur la syntaxe des conditions : @n[F] > 3 et @n[F] < 2 sont exclusives mais traitées comme inclusives. Le résultat reste correct, puisque les flux bypass gardent toutes les sorties atteignables, mais le plan peut être plus long que nécessaire. Un vrai solveur d’expressions est prévu.

Mettre les valeurs texte entre guillemets

@x[F] == Yes and non-repairable est une erreur de syntaxe : la condition ne peut pas être évaluée, le flux n’est jamais suivi et son flux otherwise l’est toujours. Écrire "Yes and non-repairable", exactement comme la valeur de la variable de sortie.

Flux supplémentaires dans le processus

Les flux otherwise, bypass et otherwise « skipped » sont de simples arêtes ajoutées à la construction du modèle de processus. Leurs ids sont déterministes : le même processus donne toujours les mêmes flux.

Tâches inclusives et acteurs

Un acteur différent est seulement préféré, jamais exigé : avec un seul acteur du rôle, les tâches inclusives sont planifiées en séquence avec des flux bypass.

08 · Sources

Où poursuivre la lecture

gind-governance-workflow-deduction-strategy-abstract/…/process/edges/FunctionLinkConditions.javaGardes, combinaison et négation, fonctions exclusives et inclusives, flux otherwise et bypass.
gind-governance-workflow-planner-default/…/scheduler/Scheduler.java · ScheduleProcess.javaLes tâches exclusives ne se bloquent jamais.
gind-governance-workflow-planner-default/…/resources/ResourceTaskGraph.java · ResourceAssigner.javaFonctions exclusives et inclusives du graphe de tâches, préférence d’acteurs des tâches inclusives.
gind-workflow-engine-prio/…/boundary/SequenceFlowConditionEvaluator.java · OtherwiseFlowObjectiveRelease.javaÉvaluation à l’exécution et libération des objectifs sautés.
…/process/nodes/WaitTasks.java · gind-workflow-engine-prio/…/skill/mediation/WaitUntilSkill.javaFonctions d’attente (Mediation, Wait Until) : sans acteur, condition et scrutation recopiées, attente à l’exécution.
gind-models-collaborative-model/…/Collaborative_MetaModel.xmlCondition Evaluation d’Implies, Supports, Needs et Sequence_Flow ; Wait Condition et Wait Polling (s) des fonctions et des tâches.