Document 17860163

advertisement
22662
>> Rustan Leino: Good afternoon, everyone, and welcome to yet another lecture
of Dr. Jean-Raymond Abrial, who is going to continue taking us through Event-B.
So far we've seen systems that make use of the events as small concurrently
executing events. And today and next time we're going to see how these are put
together into sequential programs. And then as a final advertisement, after
this lecture and the next, we'll do one more lecture, which we're going to
report on what we have done with the hypervisor that we have been working on in
the Event-B system.
So here is sequential programs.
>> Jean-Raymond Abrial: Thank you, Rustan. Good afternoon. So as Rustan
said, you have seen Event-B used in the development of system, the car and the
bridge. Half of the price, mechanic price.
We skipped the second half because there was one lecture missing. So you might
say how can we develop sequential program, because we have seen so far heavily
using events.
And events as you know is a very simple device made of guards. So it's a
predicate that are initially conditioned for the event to be triggered. And
some actions.
And that's all. Events might have parameters and some actions might be
nondeterministic but that's all. We have all these little device, all these
little events. If we want to think in terms of operationally, we have these
events a little process. And they all together run, if they are enabled. And
the sequential program is completely different. Sequential program is made of
a precondition, the specification of a specification of a sequential program is
made of a precondition and a post condition. And here we have a guard and some
post conditions. So this is completely different.
Before engaging into seeing this, I would like to hammer a bit the very
important distinction between guard and preconditions. When you have a program
defined by a precondition and post condition, it means that when you knock at
the door of this program to execute it, you have to be sure on your side the
coding that the precondition holds.
Otherwise, it crashes.
Okay? And when you refine a program, define with a precondition, you can
weaken the precondition. What does that mean? It means that -- let me take an
operational definition. You want to buy a motor and the motor has a
precondition it should work between minus 10 degrees centigrade and 30 degrees
centigrade so this is a precondition.
So you go to the vendor, the motor vendor, and you ask for exactly this motor.
And the vendor knows that he has not got exactly that. But he has a more
expensive one that goes from one minus 15 to plus 50 or something like this.
Okay. So he's going to cheat you. He's going to sell you the one that has a
weakened precondition, because it goes now from minus 15 to plus 50. And he
will not tell you.
But on your side you buy this, and that's okay, because you still believe that
it is going from minus 10 to plus 30 or whatever. And it can do more. Of
course, he has cheated you because you pay more. Okay. So this is a thing of
the weakening of the precondition.
Now, about the guard. When we have an event of say many, many times, that when
we refine, we strengthen the guard. So we go exactly into the reverse
direction. Why is that? Because we are not knocking at the door of the event.
An event is not something you call. An event is something you observe. You
observe that event's occurring. And the guard is -- again, it's enabling
condition.
So when you refine an event, why do you refine an event? You refine an event
because you have more functionalities and you enlarge maybe the state, but
maybe the condition enabling that event is now stronger. Okay. So you are
strengthening the guard.
And this could be a bit strange, because if you have a population of events,
and you strengthen the guard, you can strengthen them so much that you have
deadlock.
So this is something that never exists in the case of the precondition. Okay.
But it might happen in the case of events. That's the reason why we have to do
something the other way around. We have to prove that the refinement of a
population of events doesn't deadlock more than the population of the abstract
event you have. So you prove that the disjunction of the guard of the abstract
events implies the disjunction of the guard of the concrete event.
So it goes in the other direction. Another thing that is a bit misleading is
the following. When you prove something about a pre-post condition, what you
do on your side when you prove this program which has a pre-post condition, you
assume the precondition and you prove the post condition. And when you do the
same thing for an event, you assume the guard and you prove the post condition.
So in both cases you assume either the guard or the precondition. But I just
said two minutes ago that they are different. So why is that? It's very
simple. It's very simple. It's because if we take an operational view,
precondition is when a precondition is false, when you call something and on
your side the precondition is false, you crash.
Okay. When you observe an event whose guard is false, this guard is not
enabled. That's it. So you wait. You wait for a better time where the guard
will be true.
And why -- so it's normal because the guard is necessary condition for the
event to be triggered. So it's normal to assume the guard in order to prove
the post condition.
Now, why do you assume the precondition in order to prove the post condition in
the case of a pre-post definition? It's because it's not -- because it's not
your duty to prove the guard.
The duty is from the caller. So you assume the caller has done it. And in
fact what you have to prove is P and Q. P the precondition and Q the post
condition.
But if it is exactly the same as P and P implies Q. So that's what you do,
that's why you assume the precondition because the precondition is proved by
somebody else.
So that's it. So think about it. It's not completely obvious. And people are
a bit confused by this. But I think it's very, very, very important to make
the distinction again and again between a guard and a precondition. Okay? You
follow me? You are with me? Fine.
Let me now enter the subject.
So --
>>: So in some sense we refine, actually means to prove the disjunction of the
guards implies that then you can think of the disjunction of the guards being
the precondition of the type system and that indeed you can weaken?
>> Jean-Raymond Abrial: Yeah, you can have this. Yeah. You have to prove
that the concrete system does not deadlock more than the abstract one. This
would be very embarrassing if you do something very nice you add functionality,
but unfortunately the system deadlocks. And so you have to prove that in spite
of the fact that your strengthening the guard, the system -- the system or the
whole doesn't deadlock. Okay? So let me go now into sequential program. I'm
not going to change the idea of sequential program. We will still have pre and
post conditions. How can we encode this into a bunch of events?
So this is the story that I want to tell you today. So we are going to present
a number of examples today and next time. Array program, [inaudible] program,
middle array program, you all know this little program. Rustan has done many
of them with Daphne.
So a typical program is made of a number of multiple assignments, I assume
there are multiple assignments. Scheduled by means of some conditional
operator if iterative operators while sequential operators semicolon. So when
we have two programs we have two things that are completely different. The
assignment of value to some variables. And these things conditional iterative
and sequential.
Here is a program. Never mind what it does. We have a why. And we have an if
and if else and we have simultaneous assignment statement and we have a
semicolon. We have all the features here.
Now, how can we with advance go to this? Well, not so difficult. Suppose we
separate -- we separate completely this, this and this from this environment of
if and else and while.
So here is our paging language. So we have not put curly brackets. So as I
said before, we are just going to separate completely the individual
assignments from their scheduling, from the if and else, the while, and
semicolon.
And we favor the distribution of computation over its centralization. When you
have a sequential program, this is centralized. Everything is there. You have
the if, you do something else. You have the while, you loop. And when the
loop is finished, hopefully, we go outside and we do something else. Okay. So
this is centralized. So here we -- and it is a flavor of events. We separate
completely, and we suppose again that we have our little machines working
nicely, independently.
So an event, I refresh you, a firing addition or trigger condition, the guard,
the interaction the multiple assignments and these events are scheduled
implicitly. Implicitly in the sky there is a guard who sees all these events
and says you, you, you in a fair way of course he gives control because the
guard was a necessary condition, maybe not sufficient, it's sufficient if there
is a guard or a scheduler guard that gives control to these things.
Okay? Now, let's extract from a program an event. Here so I'm going to take
in turn all the assignments. Here J, J plus 1. And what are the conditions
for J, J plus 1 to be enabled? Well, we go down here and we see certainly when
J is different from M, because we have to enter the loop. And we have to enter
the first branch of the if and else and so this is it.
So we have extracted these little events. And we can do the same for the other
assignments. So for the second one, we are still inside the loop. We are now
in the second branch, therefore, the first predicate is false. Or, sorry, the
first predicate we take the negation of it. And then we have the third one.
So this is the second one.
And the third one forget about swap. It doesn't matter. And the third one is
just this. The guard, both predicates are false, and we are now here. And
eventually when J is equal to M, then P columns equal K. So what we have done
here, just by looking at this program, we have extracted from this program the
various events. And now let's go on to the sky as guard. And let's give
control to these things.
This is very nice, because only one of them can be tried at a time. We have no
determinicity, because all these conditions are, only one of them is true and
all of them could be true.
So you see we have now completely separated the events from the program.
What we will do is exactly the reverse. We will start from the problem,
Okay.
defining the events, like this, and then at the end, when we are happy with
them, and I will explain why, we will put them together to form the sequential
program.
Okay? So the idea is then we have just decomposed and we will do exactly the
reverse operation. So we shall first construct the events list and then we
will compose our program from these events. And of course at the beginning
when we will have the population of events, they might be nondeterministic. So
maybe several events can be filed at a time. But we don't care we have the
guard scheduler on top. When we refine strengthening the guard, we might be in
a final situation deadlock freeness, careful, we will be in a final situation
where only one events can be fired at a time. It is time now to put things
together to form the program.
Okay. So you see we have set up the scene in this way. So the idea will be to
have a specification phase where we are going to translate the pre-post
condition into some initial events. Then we head into the design phase where
you remember when we refine a population of events we can add new events and
the refine skip. And when we add events, also we have to prove that the new
events do not take control forever.
Going out of loop. Finishing a loop. That will be done in this occasion.
at the end when we are happy, we psst, we concentrate then to build the
program.
And
So it's very, very much the other way around, as what people do like starting
with the final program and trying to with very nice things like Daphne or
Boogie to prove or verify the program.
Here it's the other way around. It's top-down. Okay. Pre-post condition. We
have to encode this, the first level, with this is the famous [inaudible]
triple and we have to encode this into a population of events. Okay. So
usually what we have in the precondition is essentially a specification of the
parameters of the program. Okay. And I am supposing that the parameters of
the program, the arguments are given by value and they are not modified within
the program. No side effect. So this inside the program here, the arguments,
the parameters are constant. Ah, we have ways to define constant. We can use
context. Okay. So what we shall do is we shall use context here.
And then you will see what we do here.
Let me give you a little example.
The
search program.
This is the program that everybody used to begin with.
We are given a precondition, a natural number N, which is positive. And an
array of element, which is formalized as a function from the interval 1 N to
some state S. We are given a value V that is guaranteed to be part of the
array. So V belongs to the range of F. This is a precondition.
And we are looking post condition to an index R which is in the domain of F
such that F of R is equal to V. Okay. I have added this to simplify this
example. Of course, we could have had two answers. Nothing exists with the
value V or there is a value V and here is the index.
But I've simplified things by assuming these underlying conditions.
a pre and post condition. So this is what we want to do.
So this is
Okay. So as you can see, I have not changed anything in the usual whole triple
formality. Preprogram, post. Okay. So I've said before these things are not
going to be changed in search. So I introduce them as constants. So they are
constants. And the precondition corresponds exactly to the axioms of this
constant.
And the output parameters are variable and the post condition is a guard of
unique event. I'll explain more about this. Forget about this.
So let me encode the whole triple here. I'm defining carrier set S, because
this is generic. Three constant. NFV and I copy blindly the precondition in
the axioms. And I have a variable R, which is a result, and at this level R is
a natural number.
And the way I'm going to encode the post condition is as follows: I am
defining a very strange event which just as a guard the post condition here,
and it does nothing. Okay. So we want to go there. We want to be sure to go
there.
And here I have this thing which is a bit -- it's not dirty. It's convenient.
It's something called progress. But it does a status call anticipated, which
means that we do not consider -- we consider that we will refine this, of
course, with doing something here for R, but at this level we just consider
these two. This is just a convenient way to say that we will have something
modifying R, of course, we will have something modifying R. And this is
anticipated.
Fine. And so now we are in this situation. We are here. We
here. Okay. And now we have to go here, but we are here but
an event system. And now we are going to refine. And so the
refinement is extremely simple. We suppose that the variable
initially. And we don't know what is in the array here.
are here. We are
we are here with
idea of the
R is set to 1
And in the middle, in the current situation, we found that in the first R minus
1 -- sorry, I start at 1, not at 0. In the first R minus 1 elements of the
array, we didn't find the famous V.
And here we don't know yet. And, of course, we are sure that V is here because
it was in the axiom that V was in the range of F. So it's not here. Therefore
it's here. Here this is an image of F with the interval, within the interval 1
R minus 1. Okay? So this is what we're going to do. And for doing this we
are going to define our progress. And so progress is very, very simple. If F
of R is different from V, F of R is here in this area where we have the
question mark. If F of R is different from V, then R becomes R plus 1. So we
just move this limit one step forward. And final here is just the same as
before. But this is a new event. And the new event has to be convergence.
Okay. So we have to prove that there is a variant that makes these things
finishing eventually. So we introduce the variant, which is completely
obvious, of course. This is N minus R. And R was defined as being in 1 N as
an invariant, and NV -- and we have this also. So now this is very simple. We
are going to prove that this population of events maintain this invariant. No
problem with this one because I will just skip here. And this one -- this is
really easy -- if V is not there, and if F of R is different from V, then V is
not in 1 R. F 1 R.
Okay. So we have proved this. So we are now with these two events, progress
and final. They have -- they are deterministic. The guard is on top. And
sees this and this. So only this. Only this. While F of R is different from
V and then this eventually.
So now what we're going to do is to put them together, and in order to put them
together, we have to prove all this, of course. Of course.
And then we have to -- this is the population of event in it, progress and
final. And now we are going to do exactly the reverse that we've done before.
We are going to aggregate things. So we have to have some merging rules, and
those merging rules are completely syntactic.
So the first merging rule is as follows: If we have two events like PQ then S
and P not Q and then T, we can change them into a monster, which is still an
event because there's an event P. But here this is -- it looks like a program.
So it's in between a program and an event.
Okay. But there are some conditions. Forget about the first one here. And
the first event, so this one, must have been introduced at one refinement step
below the second one.
Why is that? Because if it has been introduced, the new event, at a refinement
step below the second one, then we would have to prove that it is convergent,
which is exactly the termination of the loop.
Okay. And a special case, this is the reason why I said don't care too much
about this one. If P is missing, then the resulting event, in quotes, has no
guard. Haha, pffft, the guard has disappeared.
And we have another one, which is exactly the same two events. You have PQ and
P not Q and we change them into if Us then SLT and ha, and the other one will
change while Q is -- while Q do S.
So why is that? So the side conditions, it's just a disjunctive condition of
the previous site conditions.
So in particular, if the two have been -- if these two have been introduced in
the same refinement step, you cannot prove that there is a termination of
something like this. So they are at the same level. That's the reason we do
that.
Okay. And that's it. That's it. So now we are going to use our rules. So
here we put progress and final together. Progress was anticipated, but we
don't count the fact that it was anticipated. So it was introduced in the
first refinement and final was introduced in the initial model.
And we proved termination here. We proved convergence here. So now we do
something called progress final, which is these two together. Okay? And this
is almost finished. And then once we have an event without guard, we like to
add in it by sequential composition at the beginning. So in it was this. So
we just add here by sequential composition. We have nothing after it, because
final will skip.
And that's it.
That's it.
We have developed a program.
Okay.
>>: [inaudible] arbitrary order.
>> Jean-Raymond Abrial:
If we have.
>>: If you have two events with those, you plug them in.
>> Jean-Raymond Abrial:
We will see this in an example.
>>: Okay.
>> Jean-Raymond Abrial: Okay. So I'm going to repeat this on other examples.
Okay. It's completely systematic. For example, let's take the very classical
binary search. Everybody takes a binary search. Okay. The same -- almost the
same specification of this example. And more usage of the merging rule. The
precondition, natural number, and this is positive. Sorted array. And value V
in the range.
This is too much. This can be proved as a theorem. And post condition,
exactly the same as before. Okay? So here is an initial situation. The only
difference with before is that we have this precondition here that the file
is -- that the array is sorted. And we have the same progress and we have the
same final as before.
Okay? So now what we are going to do is refine. And everybody knows the
binary search. This is very easy. You introduce -- we introduce two more
variables, which was not the case last time. But when we refine, we can add
variables.
And we have these two variables are in the range, in the domain of F. And V is
in the image of the interval PQ. So at the beginning of P is 1. And Q is N.
Okay?
And in the situation, in the current situation, we have something like this.
From P to Q, we have V somewhere but we don't know where.
we put R in the middle.
And we have R in --
And R is always -- this is an invariant -- in the interval P..Q.
So we have two cases. Ink. If F of R is smaller than -- if F of R is smaller
than V because the array is sorted, V is not here. It was not already here.
So it's not here now. And it's certainly here.
So we can move P to R plus 1 and so now we go between -- we consider between R
plus 1 and Q. And we have the deck, which is the symmetric one. If V is
smaller than F of R, so V is not here. So V now is here.
About R, R is still nondeterministic. It's in between P and Q. So here -sorry. Here I've assigned nondeterministically R to the interval R plus 1 Q.
R plus 1 Q. So here nondeterministically I don't care. And the same here, R
nondeterministically for P to R minus 1.
And now I'm going to refine this. So this is the situation after the first
refinement. But we are nondeterministic here and here. The events are
deterministic. But the contents of the action of the events are
nondeterministic. So the external nondeterministity is true, but the internal
nondeterminisity is not true.
We have to go further. And as you know we take, will now be chosen in the
middle of PQ. So R -- this was the abstract ink and now the concrete ink, we
take R plus 1 plus Q over 2, and here the abstract deck, and now we take the
concrete deck as this.
Okay. And now this is the end of it. So we have in it, we take also this
alleged value here. We have still this skip event here. And we have these two
people.
And these two people have been introduced in the same refinement.
candidates for if then else.
So they are
Okay. So we can do -- we use this. So ink and deck are building ink deck with
this if then else here and final is just this. So now we put ink deck and
final together. And so we apply this and clearly ink and deck, therefore ink
deck is introduced in a refinement step that is after final.
So we can now go on to this one. Or, by the way, about ink and deck we prove
that they were not, that they were not going forever. So they were convergent
and they were decreasing. It's obvious the variant is Q minus P.
And so now we can apply the while. And that gives us this.
it at the beginning and this is the final program. Okay?
And now we put in
>>: So your construction for a while says the first event has to be one hole
below the second one. Can it be more holes below?
>> Jean-Raymond Abrial:
Yes.
It can be.
>>: It has to be at least one.
>> Jean-Raymond Abrial: Yeah, yeah. Because you are sure that this is some
level below that they were you so you have proved the convergence.
Okay. So much. I told you, this is always the same. It's boring. So I'm
going maybe this is the last one. I'm going to do some more on arrays. And
last time -- next time I will do something on, with pointers. I'm not sure I
will have enough time to treat the show it example. Maybe I will do it.
And at the end I will take also some numerical examples. Okay. Among the
examples I will do next time there will be an example with two loops. Okay.
Loop inside the loop. And this is a sorting algorithm, as you could imagine.
And the problem is when you use whole triple to prove something where you have
a loop inside another loop, it's not so easy because you have an invariant
which is -- and then a second invariant inside. Whereas here this is simple
because you've got all these events. They're all flat. They're all on the
table. And you just put them together and then you put them together to form
the inner loop and then the outer loop.
So let's go into array partitioning. This is part of Quicksort as you know.
So we have an array of distinct elements. We are given a number X and we want
to construct another array G with some constraints.
And the constraints are G has got the same element as F. So the same domain.
And there exists a number K in 0 N. So outside even. And number K such that
all the elements in 1 K are smaller or equal to X and all elements in K plus 1
N are greater than X. So we partition -- we partition the thing.
So we have to rearrange F into G in order to have this situation.
Okay. So this is the classical partitioning of an array. So let's have a
little example. So we have this array. We say X is equal to 5. And now this
happens that K is also to 5.
So under this they're all smaller or equal to 5. And above K here from K plus
1 to N they are greater than 5. Strictly greater than 5 and smaller or equal
here.
So we want to achieve this. We have two special cases. In that case let X be
0 then K is here. There is nothing before. And the second special case is
when, if X is 10, greater than all of them, then K is here, from 1 to K they're
all smaller than 10. Okay? Smaller than or equal to 10.
Fine. So we start with this situation. We have the same thing. F here is an
injective function. So it's a one-to-one function. It's a total function.
And with this little thing here it means injective. So we have a one-to-one
correspondence between 1 N and the range of 1 N. And X is any number. Okay.
And about K and G, this is the result. We don't care. And final -- final I
copy here completely the thing and skip as usual. And progress here, this is
an anticipation. I allow the future progress to modify nondeterministically at
this level K and G. And now we proceed.
We introduce a variable J which is in 0 N. And the current situation is that
from 1 to K it's okay, so to speak. We are smaller than or equal to X.
From K plus 1 to J it's okay. We are greater than X. And here we don't know.
Okay. And J is going to progress this way. And this is what is described here
in this invariant. K is smaller than J. Smaller than or equal to J.
The blue here is it's here for L in 1 K then we have this. And from L in K
plus 1 J we have this. And here we don't say anything. So this is very, very
classical with array programs we just moved something. Sometimes we've seen in
the binary search we do things like this or we compare. But here this will be
exactly the same.
By the way, this notion of a pointer here, J, which moves along the data
structure, we will find out exactly the same with pointers, when we have a list
where the elements in the list are connected by pointers going to the next.
We will move like this. Okay? And sometimes we have to move the other way
around. Therefore, it's very nice to have a double link list. But there is no
different -- there is no fundamental difference between the array and list by
pointers. We will always do the same sort of thing. Here it's very convenient
with arrays because we can play with intervals. And there are very nice notion
about intervals if L is in 1 K, L is greater than or equal to 1 and smaller
than or equal to K. So we can have arithmetic reasoning in order to do these
things.
And with pointers, this is exactly the same thing. But the mathematical
structure is a bit more complicated, because it is in fact the transitive
closure of the relation of the function defined by the pointers.
First refinement.
So this is the invariant for the first refinement.
And now let me do a little animation here. We partitioned this with 5.
here to begin with. And then we compare -- we compare this with 5.
J is
And it's greater than 5. So we can move. And here we compare it with 5. So
it's smaller than 5 or equal to 5. So we are going to interchange. Okay. And
the same here. And yet this is smaller. So we can move. Smaller. We can
move. Bigger so we are going to exchange 4 and 7. And then 1 and we'll change
1 and 8 and that's it because we have reached the end.
So the refining events, so these are not changed. Oh, yes, here we have -there is a data refinement here. We have J equal to N.
And we have to prove, of course, that it refines its abstraction. And here
progress 1, we must prove that it is convergent. And we have this situation.
So JG plus 1 is greater than X so we just move on the right. This is the
situation there. And we have the variant N minus J which is very important.
So this is convergent.
Progress two, which is JG plus 1 is smaller than, it's smaller or equal to X,
so we could also move. And we move K and J. And finally here we have to swap
in this situation we swapped the two values here.
And we have to prove again that they maintained the invariant and that they
decreased the variant.
And so this is the animation. And now this is the end of it. We put together
progress 2 and progress 3, which were defined at the same level. So this is an
if then. And then we have P and Q. P and not Q.
So that gives us -- and again another merging rule with an if then else if we
already have an if then.
So now we have progress 2, 3, so we put the three together. And now we put
this together with progress 1 and this was not at the same level as this one.
So we can do a while, and we have two contradictory conditions here. And the
same G different from N. So we have this and now this is the final. We put
the loop on top. And we add the init and that's the program. By the way, this
is the program I showed you at the beginning.
So you've seen how we have done it completely the other way around. Okay. 18
proved, and six were interactive. So I think Daphne and Boogie would do better
on this.
So we are like Avis, we are working very hard to have more automation into,
with the prover. Okay? All right. That's something. So we will do that next
time.
>>: You did not show sequential composition.
>> Jean-Raymond Abrial:
No, I did not show sequential composition.
>>: Next lecture or did you want to say something?
>> Jean-Raymond Abrial: No, we know that much. But I will explain how it
could be done with, there are various -- there's a little of sequential
composition at the beginning when I add in it or at the end if final would have
something to do which was not the case here. So we have already seen a little
of sequential composition. But there are two other cases which I will describe
a bit next time.
>>: Two other questions.
When you introduced the variant, you used the same
invariant for all of the events refined at one level.
>> Jean-Raymond Abrial:
The same variant.
>>: Right. How is that -- where is that stated? I mean, in Event-B, there's a
little section for each event to say where you can include an invariant -where you can include the variant.
>> Jean-Raymond Abrial:
is unique.
When you say that it is convergent.
But the variant
>>: So if you refine two different events, and you want each -- and you want
them to have the same variant function, do you just state the same variant
function in both places?
>> Jean-Raymond Abrial: No, you don't put a variant function into the event.
The variant function is at the level of the machine.
>>: Oh, I see.
>> Jean-Raymond Abrial:
There is a unique.
>>: I see, unique one for the entire machine.
>> Jean-Raymond Abrial:
Entire machine.
>>: That makes sense.
>> Jean-Raymond Abrial: That's actually fundamental, because if you have a
different variant, this is okay for this one. This is okay for this one, but
they could play Ping-Pong. Okay? So it's -- no, no, this is very important,
this is the same -- and that's the reason why we can do an if then else,
because each branch of they are in the same level and each branch has decreased
the variant. And this was.
>>: The possibilities will individually decrease the variance.
>> Jean-Raymond Abrial:
Decrease.
>>: Doesn't matter which one you pick.
>> Jean-Raymond Abrial:
Yeah, yeah.
>>: And my final question is, can you say something more about the status of
the anticipated events?
>> Jean-Raymond Abrial:
Okay.
>>: What's different with them?
>> Jean-Raymond Abrial: At the beginning we have no anticipation. Okay. Now,
if you have no anticipation, you remember that a new event must refine skip.
Okay. So the problem is if we have no anticipation, we could not play with R,
the result, because the result is just in it and final doesn't do anything.
So in order to cope with this, we couldn't have a final doing skip, the final
has to do something precisely to assign a certain value.
And then the new event that we are introducing cannot play with R.
to play with something else, let's say S.
They have
So S is a variable that's used in the process and at the end we assign R to S.
And it's boring. If R and S are smallest thing, that's okay. But if R and S
are big things, you cannot work like this.
So it took us a long time to figure out this notion of anticipation.
So the idea of anticipation is the following: I have seen in an unanticipated
event R becomes any number. So it's completely nondeterministic. From the
point of view of the level where it is introduced, it is just there because we
want later to use, to assign in the real progress some value to R.
But from the point of view of convergence, we are not proving the convergence
there. We anticipate that the refinement will be convergence. And so that's
exactly it. So most of the time all the time the progress was an unanticipated
event, and in the next refinement progress is really introduced and would
change the status from unanticipated to convergence.
And something might stay -- in several steps might stay anticipated
unanticipated and at some point it becomes convergent.
>>: If I zoom in to a design at the particular model and I see an event there
is anticipated, from the point of view from above, I should just ignore it
then?
>> Jean-Raymond Abrial: Yeah, you would ignore it. Yeah. It's a convenient
way -- and most of the time it's doing something that is completely
nondeterministic.
By the way, we were thinking of a feature in our formalism. We have skip that
does nothing, and we were thinking of something like called keep. Keep is
nondeterministically changed things in order for the invariant to hold. It's
like a havoc. It's a bit like a havoc. But it's a havoc that maintains the
variant.
>>: Havoc followed assuming the variant.
>> Jean-Raymond Abrial: Exactly. And we had discussion on this and finally we
didn't do it. But it could be exactly where this keep or havoc or sort of
havoc could have been used.
Further questions?
[applause]
No?
Okay.
Download