• Aucun résultat trouvé

Spécification du système fermé

Chapitre 5 Génération du code Uppaal d’un ordonnanceur

5.3 Application à l’ordonnanceur

5.3.2 Spécification du système fermé

Cette section présente la traduction de la spécification B de l’ordonnanceur en Uppaal. Afin d’exprimer l’interaction entre les différents processus du système, nous avons ajouté des clients client1 et client2. Ces clients communiquent avec un nouveau processus choice qui choisit de faire wakeup ou request.

Considérons un système formé d’un ordonnanceur scheduler interagissant avec deux clients client1 et client2. Chaque client envoie sa demande de computation en indiquant son identité, la durée de calcul demandée duration et son délai critique delay. Cette demande de calcul, émise sur le canal computation, est acheminée à un autre processus appelé choice. Ce dernier, qui se synchronise avec les deux clients, va tester s’il s’agit d’une première demande (l’ordonnanceur n’a aucune demande en cours) et dans ce cas envoyer le signal wakeup à l’ordonnanceur, ou d’une demande ultérieure et envoyer le signal request à l’ordonnanceur.

La figure 5.11 illustre les clients client1 et client2 ayant respectivement les valeurs 10 et 7 affectées à duration et 15 et 10 assignées à delay. L’affectation de ces valeurs dans les tableaux respectifs doit être directement suivie de l’envoi de computation. Donc les états s1 sont déclarés “committed”.

start s1 s2 pp= 0, duration[0]= 10, delay[0]= 15 computation! support[0]== false start s1 s2 pp= 1, duration[1]= 7, delay[1]= 10 computation! support[1]== false

Figure 5.11: Automates des clients

L’automate du processus choice est représenté par la figure 5.12. Lorsque ce processus reçoit un signal sur le canal computation, il doit se synchroniser rapidement avec l’ordonnanceur par le canal

wakeup ou request. Pour cela, l’état s1 de cet automate est déclaré “committed”. start computation? s1 vide() wakeup! !vide() request!

Figure 5.12: Automate de choice

L’ordonnanceur est représenté par l’automate de la figure 5.13. Il est construit en respectant les règles énoncées dans le principe de transformation de la section 5.2.2. Pour plus de détails sur le code Uppaal complet des différents processus client1, client2, scheduler avec leurs caractérstiques, ainsi que les déclarations globales des variables et des fonctions, le lecteur est invité à consulter l’annexe F.

Simulation Rappelons que l’outil Uppaal comprend un simulateur où l’on peut avoir une vue sur le comportement du système. La simulation de la figure 5.14 montre que client2 a d’abord demandé le processeur via le canal computation. Le processus choice a envoyé au scheduler un signal via le canal wakeup. L’ordonnanceur l’a bien reçu et a effectué les traitements liés à ce canal. Le processus client1 a ensuite demandé une computation à choice.

Vérification L’outil Uppaal contient également un vérificateur de propriétés de vivacité, de sûreté, d’accessibilité, . . . (section 3.3.1 du chapitre 3). Après avoir modélisé et simulé notre spécification, nous pouvons maintenant la tester par des propriétés exprimées en logique CTL. L’ordonnançabilité est ex- primée ici par l’absence de deadlock qui peut être spécifiée en logique CTL par la contrainte temporelle “A[] not deadlock”. La vérification de la propriété “E<> deadlock” sur notre système d’automates mon- tre, comme l’illustre la figure 5.15, qu’il existe un chemin aboutissant à un blocage. Ceci vient du fait que les valeurs choisies pour duration et delay mènent à une violation du délai critique et par suite l’exemple choisi n’est pas ordonnançable par EDF. En effet, un système est ordonnançable par EDF si la charge processeur U  1 (section 3.2.2 du chapitre 3). Un calcul manuel sur notre exemple montre que la charge processeur U est égale à1;36>1.

Nous avons considéré également un autre exemple ordonnançable avec EDF. La vérification de la propriété “A[] not deadlock” spécifiant l’absence de blocage sur cet exemple a été menée à bien comme le montre la figure 5.16.

Notons que notre méthode permet d’aller plus loin que la simple vérification d’ordonnançabilité de tâches cycliques. Les occurrences des demandes d’allocation sont exprimées par des automates tem- porisés, et les propriétés vérifiables sont exprimables avec des formules CTL prenant en compte des variables d’état des systèmes modélisés.

5.4

Conclusion

Nous avons présenté dans ce chapitre la traduction en Uppaal de la modélisation B des ordonnanceurs. L’implantation qui aboutit à un langage exécutable, peut s’effectuer en utilisant le langage B0 classique

et en respectant ses restrictions. Nous avons donné un exemple de raffinements successifs de la ma- chine istacks permettant de modéliser les processus préemptés. Ces raffinements aboutissent à la fin à l’implantation en B0 de cette machine. Ensuite, nous avons présenté le langage B0_Uppaal en définissant la structure de la machine B pouvant être traduite en automates Uppaal.

Puis nous avons abordé brièvement les dernières extensions apportées à l’outil Uppaal comme par exemple les fonctions, les quantificateurs et la déclaration de types. Afin de transformer le code B de l’ordonnanceur en automates Uppaal, nous avons défini certaines règles à respecter lors de cette traduction. Nous avons transformé les machines feuilles de notre hiérarchie B en Uppaal afin de former un automate ordonnanceur. Nous avons illustré le comportement de cet ordonnanceur en le synchronisant avec deux clients qui demandent l’accès au processeur.

Enfin, nous avons vérifié cette traduction par un test d’ordonnançabilité en considérant deux exem- ples, l’un est non ordonnançable et l’autre est ordonnançable. Pour le premier, nous avons vérifié s’il satisfait la propriété “il existe un blocage” et pour le second, nous avons testé “l’absence de blocage”. Ces deux propriétés ont été bien satisfaites par le vérificateur Uppaal.

5 .4 . C o n cl u si o start ((support[running]==true &&

support[pp] == true &&

pp != running) imply (cl[running] <= comp[running])) &&

forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p]))

s1

forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p]))

s2

forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p])) s3

(forall (q:PROCESS) support[q] imply cld[q]-cld[pp] <= delay[q]-delay[pp]) && forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p]))

s4

forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p])) s5

forall (p:PROCESS) support[p] imply ((cld[p] <= delay[p]) && (cl[p] <= comp[p]))

cl[pp]=0, comp[pp]= duration[pp], running= pp, t_init(pp) request? t_enlarge(pp), cl[pp]=0, comp[pp]= duration[pp] cl[running] <= comp[running]-duration[running] cld[running]-cld[pp] <= delay[running]-delay[pp] push(running), running= pp cld[running]-cld[pp] > delay[running]-delay[pp] !empty t_link(itop,running) empty

(cl[running] >= comp[running]) && running_is_last() maz(),

t_remove_last(running) support[pp] == true && pp != running && cl[running] >= comp[running]

t_remove(running) !empty comp[itop]= comp[itop]+comp[running]

empty

running= pp !empty && itop==pp

pop() empty or itop!=pp cl[pp]=0 F ig u re 5 .1 3 : A u to m at e d e l’ o rd o n n an ce u r 1 3

Conclusion et perspectives

Durant cette thèse, nous avons effectué une étude détaillée des langages de description d’architecture où nous avons présenté les langages Wright, ACME, Rapide, AADL et COTRE. Ce dernier est exploité pour modéliser les différentes politiques d’ordonnancement temps réel. Ces politiques sont nécessaires à ordonnancer les tâches d’un système temps réel critique, où on doit satisfaire certaines contraintes temporelles.

Ensuite, nous avons abordé les différentes techniques de vérification de modèles comme par exemple, la méthode B, les automates temporisés et hybrides, ainsi que les logiques temporelles et temporisées. Nous nous sommes basés durant nos travaux, sur la méthode B pour modéliser des ordonnanceurs. C’est une méthode de développement basée sur le mécanisme de raffinement. Ce mécanisme est composé de plusieurs étapes, dont la dernière est l’implantation. La méthode B nous a permis de vérifier et de valider la modélisation Cotre des ordonnanceurs.

Puis nous avons introduit l’ordonnancement temps réel et abordé les politiques RM, DM, EDF, et LL permettant d’attribuer le processeur à la tâche la plus prioritaire selon différents critères. Nous nous sommes basés sur la politique EDF pour illustrer notre travail. Nous avons présenté également les outils de model-checking Uppaal et HyTech, ainsi que les outils de vérification d’ordonnançabilité TIMES et Cheddar. Nous avons étudié aussi certaines approches existantes pour la modélisation et la vérification des ordonnanceurs temps réel.

Notre contribution peut se récapituler comme suit:

 La modélisation des politiques d’ordonnancement en utilisant le langage Cotre.  La validation de cette modélisation en se basant sur la méthode B.

 La génération du code Uppaal des ordonnanceurs.

Dans la première partie de notre contribution, nous avons présenté une méthode de modélisation des ordonnanceurs temps réel à l’aide du langage Cotre. Afin de modéliser la préemption, nous avons proposé une démarche reposant sur le retardement de la borne de calcul. Cette démarche nécessite une étape de vérification afin de s’assurer de la correction de l’implémentation de l’ordonnanceur. Ceci nous a amené à exploiter l’outil AtelierB incorporant un générateur d’obligations de preuve devant être vérifiées afin de valider la spécification. La spécification B des politiques préemptives repose sur plusieurs étapes de raffinements introduisant l’ordonnancement atemporel, la gestion du temps à l’aide des chronomètres puis par les horloges des automates temporisés.

La deuxième partie consiste à générer un modèle que l’on peut vérifier automatiquement. Il se base sur un sous-ensemble de B, variante du langage B0 des implantations traduisibles en C. Suite aux restrictions présentes dans ce langage, nous avons présenté une méthode permettant de transformer une machine B en un automate Uppaal, en respectant certaines règles.

Une voie pour la continuation de cette contribution serait de générer un outil permettant de faire la transformation automatique d’une machine B en automate Uppaal, tout en implémentant les règles

nécessaires. La validation de cette étape peut être effectuée en s’appuyant sur la sémantique des machines B et des automates Uppaal. Cette étape est délicate puisque les horloges introduites en B sont discrètes, alors que Uppaal suppose le temps continu. Il faudrait donc comparer le raffinement B et le raffinement temporisé.

Une autre extension de cette étude concerne la génération d’ordonnanceurs exécutables exprimés par exemple en C. Deux voies sont possibles: soit à partir d’Uppaal, soit à partir de B, mais il faut pour cela atteindre le niveau B0. La comparaison de ces stratégies de génération serait aussi intéressante à étudier. A un niveau plus méta, l’introduction d’opérateurs de composition de machines B est aussi apparue intéressante et éviterait la génération d’obligations de preuve, leur vérification étant acquise par con- struction.

Caractéristiques de quelques ADLs

Wright ACME Rapide COTRE

Interface - Les points de l’interface - Les points de l’interface - Les points de l’interface - Les points de l’interface sont les ports. sont les ports. sont les constituants sont les ports.

- La sémantique de (provides, requires, l’interaction des ports action et service).

est spécifiée en CSP.

Types - Types extensibles. - Types extensibles. - Types extensibles. - Horloges.

- Ports paramétrables. - Paramétrisation possible - Contient un sous langage - Contient un sous langage avec les templates. de types. de types.

- Supporte les - Supporte les paramétrisations. paramétrisations.

Sémantique - Exprimée en CSP. - Les modèles sémantiques - Ensemble d’événements - Automates temporisés. d’autres ADLs sont utilisés partiellement ordonnés.

dans des listes de propriétés.

Contraintes - Protocoles d’interaction - Via les interfaces - Via les interfaces et les - Invariants d’état. pour chaque port en CSP. uniquement. sémantiques.

- Contraintes algébriques sur l’état des composants. - Contraintes sur les posets.

Evolution ou - Via les instanciations - Sous-typage structurel - Héritage (sous-typage - Inexistante.

Réutilisation de paramètres. via extends. structurel).

Propriétés non - Inexistantes. - Permet n’importe quel - Inexistantes. - Propriétés temporelles

fonctionnelles attribut dans les listes de sur les horloges. propriétés, mais n’opère

pas sur eux.

Wright ACME Rapide COTRE

Interface - Les points de l’interface - Les points de l’interface - Inexistante. - Types des données sont les rôles. La sémantique sont les rôles. - Autorise les composants échangées. - La sémantique de connexions.

l’interaction des rôles est spécifiée en CSP.

Types - Types extensibles basés sur - Types extensibles basés - Inexistants. - Inexistants. les protocoles. sur les protocoles.

- Rôles et glue paramétrables. - Paramétrisation possible avec les templates.

Sémantique - Sémantique de la glue - Les modèles sémantiques - Connections - Automates exprimée en CSP. d’autres ADLs sont utilisés conditionnelles. communiquants.

dans des listes de propriétés.

Contraintes - Via les interfaces et les - Via les interfaces et - Inexistantes. - Plusieurs protocoles sémantiques. structurelles pour les (1!1, 1!n, . . . ).

- Protocoles d’interaction instances de types. pour chaque rôle en CSP.

Evolution ou - Via différentes instanciations - Sous-typage structurel via - Inexistante. - Inexistante.

Réutilisation de paramètres. extends.

Propriétés non - Inexistantes. - Permet n’importe quel - Inexistantes. - Inexistantes.

fonctionnelles attribut dans les listes de propriétés, mais n’opère pas sur eux.

Tableau A.2: Modélisation des connecteurs

Wright ACME Rapide COTRE

Compréhension - Spécification textuelle - Spécification textuelle - Spécification textuelle - Spécification textuelle concise. concise. avec des détails sur concise.

les connecteurs.

Composition - La glue est considérée -Via les templates, les - Les mappings associent - Instanciation de comme une architecture. représentations et les une architecture à une composants.

rep-maps. interface.

Raffinement - Inexistants. - Rep-maps. - Le raffinement permet - Inexistants.

et Traçabilité de comparer les

architectures à différents niveaux.

Hétérogénéité - Supporte des éléments - Listes de propriétés - Supporte le développement - Inexistante. fins. ouvertes. de simulations via le sous-

langage exécutable de Rapide.

Mise à l’échelle - Configurations explicites - Configurations explicites - L’ajout d’un nouveau - Modèles paramétrés. - Nombre variable de rôles. - Nombre limité de rôles. composant exige la

modification des connecteurs existants.

Evolution ou - Convient aux configurations - Configurations explicites. - Pas de support pour les - Inexistante.

Réutilisation partielles. architectures partielles.

Dynamisme - Dynamisme contraint: - Inexistant. - Dynamisme contraint: - Inexistant. insertion et élimination. configuration conditionnelle

et génération d’événements dynamique.

Contraintes - Les ports peuvent être - Les ports peuvent être - Le raffinement est contraint. - Inexistantes. attachés aux rôles et attachés aux rôles et - Langage de poset temporisé.

vice-versa. vice-versa.

Propriétés non - Inexistantes. - Permet n’importe quel - Permet la modélisation du -Propriétés temporisées.

fonctionnelles attribut dans les listes de temps dans le langage des propriétés, mais n’opère contraintes.

pas sur eux.

Machines B

B.1

Machine timed_nonpreemptive

REFINEMENT timed_nonpreemptive REFINES untimed_nonpreemptive SEES common ABSTRACT_VARIABLES cle, cld CONCRETE_VARIABLES ready, running DEFINITIONS

ct(cld)==8pp.(pp2ready)(cld)(pp)delay(pp));

cons(cle)==8pp.(pp2ready)(cle)(pp)duration(pp))

INVARIANT

cld2ready!N ^ cle2ready!N ^ (running62ready)ready =;) ^ ct(cld) ^ cons(cle) ^ 8pp.(pp2ready - {running})cle(pp) = 0)

INITIALISATION

cld :=;kcle :=;kready :=;krunning:2PROCESS

OPERATIONS SKIP =

SELECT ((ready6=;)^(ct((cld;succ)))^(cons(cleC {runningj >cle(running)+1}))) THEN

cle(running) := cle(running) + 1kcld := (cld;succ)

END ; wakeup(pp) =

BEGIN

ready := {pp}kcld(pp) := 0kcle(pp) := 0krunning := pp

END ; request(pp) =

BEGIN

ready := ready[{pp}kcld(pp) := 0kcle(pp) := 0

END ; election(pp) =

SELECT cle(running)duration(running)^pp2ready - {running} THEN

ready := ready - {running}kcld := {running}C– cldkcle := {running}C– clekrunning := pp

END ; stop =

SELECT cle(running)duration(running)^ready = {running} THEN

ready :=;kcld :=;kcle :=;

END END

B.2

Machine fcfspolicy

REFINEMENT fcfs_policy REFINES timed_nonpreemptive SEES common VARIABLES cl, cld DEFINITIONS ct(cld)==8pp.(pp2ready)(cld)(pp)delay(pp))

; cons(cl)==(running2ready)clduration(running) )

; isfcfs== (running2ready)max(ran(cld))cld(running))

INVARIANT

cld2ready!N ^ cl2N /*horloge d’exécution*/

^ (running2ready =) cl = cle(running))

^ isfcfs ^ ct(cld) ^ cons(cl)

INITIALISATION

cld :=;kcl := 0kready :=;krunning:2PROCESS

OPERATIONS SKIP =

SELECT ready6=;^cons(cl + 1)^ct((cld;succ)) THEN

cl := cl + 1kcld := (cld;succ) END ; wakeup(pp) = BEGIN ready := {pp}kcld(pp) := 0kcl := 0krunning := pp END ; request(pp) = BEGIN ready := ready[{pp}kcld(pp) := 0 END ; election(pp) =

SELECT clduration(running)^pp2ready - {running}

^(max(ran({running}C– cld))cld(pp))

THEN

ready := ready - {running}kcld := {running}C– cldkcl := 0krunning := pp

END ; stop =

SELECT clduration(running)^ready = {running} THEN

ready :=;kcld :=;

END END

B.3

Machine priority_graph

MACHINE priority_graph(ELEM) VARIABLES R_priority, support DEFINITIONS "prio.def" INVARIANT

support2FIN(ELEM) ^ op(R_priority, support)

INITIALISATION

R_priority :=;ksupport :=;

OPERATIONS init(pp) =

PRE pp2ELEM^support =;THEN

R_priority := {ppj >pp}ksupport := {pp}

END ; enlarge(pp) =

PRE pp2ELEM THEN

ANY rp WHERE

op(rp, support[{pp})^rp\supportsupport = R_priority

THEN

R_priority := rpksupport := support[{pp}

END END;

result priority(p1, p2) =

PRE p12ELEM^p22ELEM^p12support^p22support THEN

result := bool((p1,p2)2R_priority)

END ; link(p1 , p2) =

PRE p12ELEM^p22ELEM^p12support^p22support^(p2, p1)62R_priority THEN

R_priority := R_priority[(R_priority 1

[{p1}]R_priority[{p2}])

END ; remove(head) =

PRE head2ELEM^head2support^maximum(R_priority, head) THEN

R_priority := R_priority\((support - {head})(support - {head}))ksupport := support - {head}

END ;

remove_last(head) =

PRE head2ELEM^support = {head} THEN

R_priority :=;ksupport :=;

END END

B.4

Machine timed_priority_graph

MACHINE timed_priority_graph SEES common INCLUDES priority_graph(PROCESS) VARIABLES cld DEFINITIONS ct(cld) ==8pp.(pp2support =) (cld)(pp)delay(pp)) ; "prio.def" INVARIANT cld2support!N ^ ct(cld) INITIALISATION cld :=; OPERATIONS tick =

PRE support6=;^ct(cld;succ) THEN

cld := (cld;succ)

END ; t_init(pp) =

PRE pp2PROCESS^support =;THEN

cld(pp) := 0kinit(pp)

END; t_enlarge(pp) =

PRE pp2PROCESS THEN

cld(pp) := 0kenlarge(pp)

END ;

result t_priority(p1, p2) =

PRE p12PROCESS^p22PROCESS^p12support^p22support THEN

result priority(p1, p2) END ;

t_link(p1,p2) =

PRE p12PROCESS^p22PROCESS^p12support^p22support^(p2, p1)62R_priority THEN

link(p1,p2) END ;

t_remove(head) =

PRE head2PROCESS^head2support^maximum(R_priority, head) THEN

cld := {head}C– cldkremove(head)

END ;

t_remove_last(head) =

PRE head2PROCESS^head2support^support = {head} THEN

cld :=;kremove_last(head)

END END

B.5

Machine preemptive_priority

REFINEMENT preemptive_priority REFINES scheduler

SEES common

INCLUDES priority_graph(PROCESS), istacks(PROCESS) VARIABLES running

DEFINITIONS "prio.def" INVARIANT

ran(istack)support

^ (running62support)support =;)

^ (running2support)maximum(R_priority, running))

^ running62ran(istack) ^ support = ready

^ 8ii.(ii21..(size(istack)-1))(istack(ii)j >istack(ii+1))2R_priority)

ASSERTIONS

8pp.(pp2support - {running}^(maximum(R_priority\((support - {running})(support - {running})), pp)) ^pp2ran(istack))last(istack) = pp)

INITIALISATION running:2PROCESS

OPERATIONS SKIP = skip ; wakeup(pp) = BEGIN running := ppkinit(pp) END ; request(pp) = VAR more_prio IN enlarge(pp) ; more_prio priority(running, pp) ; IF more_prio = TRUE THEN

push(running)krunning := pp k IF istack6=;THEN link(last(istack), running) END END END ; election(pp) =

SELECT pp2support - {running}

^ maximum(R_priority\((support - {running})(support - {running})), pp)

THEN

remove(running)krunning := pp k IF istack6=[]^last(istack) = pp THEN

pop END END ; stop =

SELECT support = {running} THEN remove_last(running)

END END

B.6

Machine preemptive_timed_priority

REFINEMENT preemptive_timed_priority REFINES preemptive_priority

SEES common

INCLUDES timed_priority_graph, istacks(PROCESS) VARIABLES running, cle

DEFINITIONS "prio.def"

; ct(cld) ==8pp.(pp2support)(cld)(pp)delay(pp))

; cons(cle) ==8pp.(pp2support)(cle)(pp)duration(pp))

INVARIANT

cle2support!N

^ cons(cle)^8pp.(pp2ran(istack))cle(pp)6=0)

^ 8pp.(pp2support^cle(pp)6=0^pp6=running)pp2ran(istack))

ASSERTIONS 062cle[ran(istack)]

INITIALISATION cle :=;krunning2PROCESS

OPERATIONS SKIP =

SELECT support6=;^cons(cleC {runningj >cle(running)+1})^ct(cld;succ) THEN

cle(running) := cle(running) + 1ktick

END ; wakeup(pp) =

BEGIN

cle(pp) := 0krunning := ppkt_init(pp)

END ; request(pp) =

SELECT cle(running)6=0 THEN

VAR more_prio IN t_enlarge(pp) ; cle(pp) := 0

; more_prio t_priority(running, pp) ; IF more_prio = TRUE THEN

push(running)krunning := pp k IF istack6=;THEN

t_link (last(istack), running) END

END END END ; election(pp) =

SELECT cle(running)duration(running)^pp2support - {running}

^ maximum(R_priority\((support - {running})(support - {running})), pp)

THEN

t_remove(running)kcle := {running}C– clekrunning := pp k IF istack6=[]^last(istack) = pp THEN

pop END END ; stop =

SELECT cle(running)duration(running)^support = {running} THEN

cle :=;kt_remove_last(running)

END END

B.7

Machine preemptiveuppaal

REFINEMENT preemptiveuppaal REFINES preemptive_timed_priority SEES common

INCLUDES timed_priority_graph, istacks(PROCESS) VARIABLES running, comp, cl

DEFINITIONS "prio.def"

; ct(cld) ==8pp.(pp2support =) (cld)(pp)delay(pp))

; cons(cl) ==8pp.(pp2support =) (cl)(pp)comp(pp))

; preempts(nn) == istack(nn-1)

INVARIANT

comp2PROCESS!N /*durée de calcul*/ ^ cl2PROCESS!N /*horloge d’exécution*/

^ cons(cl) ^ (running2support =) cl(running) = cle(running) + comp(running) - duration(running)) ^ 8nn.(nn2dom(istack)^nn>1 =) cl(preempts(nn)) =

cle(preempts(nn)) + cl(istack(nn)) + comp(preempts(nn)) - duration(preempts(nn)))

^ (running2support =) cl(last(istack)) =

cle(last(istack)) + cl(running) + comp(last(istack)) - duration(last(istack)))

INITIALISATION

cl := PROCESS{0}krunning:2PROCESSkcomp := PROCESS{0}

OPERATIONS

SKIP = SELECT ((support6=;)^(cons((cl;succ)))^(ct((cld;succ)))) THEN

cl := (cl;succ)ktick

END ;

wakeup(pp) = BEGIN cl(pp) := 0kcomp(pp) := duration(pp)krunning := ppkt_init(pp) END ;

request(pp) = SELECT cl(running)>comp(running) - duration(running) THEN

VAR more_prio IN t_enlarge(pp) ; cl(pp) := 0

; comp(pp) := duration(pp)

; more_prio t_priority(running, pp)

; IF more_prio = TRUE THEN push(running)krunning:= pp k IF istack6=;THEN t_link(last(istack), running) END END END END ;

election(pp) = SELECT cl(running)comp(running)^pp2support - {running}

^ maximum(R_priority\((support - {running})(support - {running})), pp)

THEN

t_remove(running)

k IF istack6=[] THEN comp(last(istack)) := comp(last(istack)) + comp(running) END k running := pp

k IF istack6=[]^last(istack) = pp THEN pop

ELSE cl(pp) := 0 END

END ;

stop = SELECT cl(running)comp(running)^support = {running} THEN

cl := PROCESS{0}kt_remove_last(running)

END END

Preuves interactives dans l’Atelier B

C.1

Le prouveur interactif de l’atelier B

L’atelier B est un outil permettant générer automatiquement les obligations de preuve. Ces obligations doivent être prouvées pour assurer la cohérence des machines abstraites, ainsi que la vérification des raffinements et des implémentations.

L’outil de preuve de l’Atelier B comporte deux prouveurs de théorèmes: un prouveur automatique et un prouveur interactif. La preuve d’un composant est terminée lorsque toutes ses obligations de preuve sont prouvées. L’application du prouveur automatique sur un composant B permet de lancer la preuve automatique sur chaque obligation de preuve qui n’a pas été encore prouvée. Les résultats sont affichés sur la sortie standard: un +indique une preuve réussie et une preuve échouée. La force représente la complexité des tactiques employées par le prouveur automatique, c’est à dire que plus la force est élevée, plus le prouveur automatique est efficace. Mais, ceci nécessite un temps de calcul très élevé et une capacité de mémoire plus grande.

Quand le prouveur automatique échoue sur une obligation de preuve, il faut la prouver en mode interactif. On peut également utiliser le prouveur interactif afin de réaliser certaines preuves d’une façon manuelle.

En appliquant le prouveur interactif sur un composant B, une fenêtre mentionnant la situation glob- ale de ce prouveur apparaît. Elle permet d’afficher la liste des obligations de preuve avec leur état "proved" ou "unproved". Le bas de cette fenêtre liste les différentes commandes de la preuve sous forme arborescente. Un double-click sur une obligation de preuve positionne la preuve interactive sur cette obligation et permet l’apparition de deux fenêtres. La première contient les hypothèses courantes, et la seconde affiche le but courant et permet également l’introduction des commandes. Lorsque la preuve est terminée, la zone indiquant le but se colore en vert et l’état de l’obligation de preuve correspondante devient "proved".

Le prouveur interactif introduit plusieurs commandes de preuve. Elles correspondent intuitivement aux règles d’inférence du système de déduction intégré dans l’Atelier B. L’application d’une commande permet de transformer le but courant en un ou plusieurs nouveaux buts à prouver. Par exemple, la commande pr permet de lancer le prouveur automatique sur le but courant. Notons qu’on dispose en

Documents relatifs