 Hi and welcome back to program analysis. So this is part four of this lecture on operational semantics and What we'll do in this fourth part is to now look at another way to define the semantics of the language which is actually the most common way perhaps to Define the semantics of a language and these are structural operational semantics We look at two flavors of those and we'll start here in this video with the small step semantics Which is the first of these two flavors? So now if you've seen the previous video then you've seen already one way of defining the semantics of our language and this was this abstract machine So basically a hypothetical computer just built to execute simp programs Now this is one valid way of doing it But as you've also seen the abstract machine was actually pretty detailed. So a lot of the Rules were not really spent on doing actual computation But on something else and in particular there were quite a few transitions that are part of the abstract machine That are basically only about manipulating the syntax of the language so for example, there were some rules that were just about Taking a command and then decomposing it into its components in order to then reason about the meaning of these components So what we now want to do instead is to focus on a way to define the semantics where every transition is Actually a computational step and one benefit of doing this of course is that you can write down the semantics of a program with fewer transitions because you only have to write down the actual computational steps and we'll do this in two styles Where one and that's the one that we are going to look at in this video It's called small step semantics and this name implies the steps that we're taking here in each transition are relatively small Sometimes this is also called reduction semantics. So this is just in case you See this word somewhere else so you know that you now know about it and then the second style of Structural operational semantics that we look here look at here will be Dix big step semantics Which is sometimes also called evaluation semantics All right So let's get started with the small step semantics and again, we will define the semantics as a transition system So again, we need to define both the configurations that this transition system is about and the transition Relations that tell us how to get from one of those configurations to another So we here will have a transition system with a configuration And in our case this configuration now consists only of a pair So it's not the triple as before but just the pair where we have the program itself And then the so-called store which you can think of as something very similar to the memory of the abstract machine So P is the program and s is the store Which actually is a function from locations to integers so similar to the memory Now the configuration is easy to define now the slightly harder part which will take a few more minutes is to actually define the transition rules or to define this transition relation that tells us how to get from one configuration to the other and In line with the name reduction semantics that I've mentioned before Sometimes these relations are also called reduction relations and the way We'll define these relations is by defining axioms and rules that tell you when you can actually Conclude that you can get from one configuration to another Similar to what we've done for the abstract machine Let's start by defining the axioms and rules for expressions in our simple language And let's start with the most simple of all of these axioms Which is an axiom that tells us how to actually read the value of a variable From the memory So in this case, we again will use this Horizontal bar notation that we've seen in the first video of this lecture Where we do not have anything on top of the bar because this is an axiom so we do not have any hypothesis and then At the bottom We have the conclusion we can draw which is that if we have a program where we say read the location the value at location L and we have a given store then we can reduce this to a value n and the same store again if at Location L We actually have this value n and I'm going to give each of these rules a name So this is a rule called bar for variable Because this is essentially reading the value of a variable and please note that Reading a variable from the store does not really change the store itself because we're not writing anything But just reading something So there's no change of the store s itself The next axiom will be for evaluating Operations so once we've read some values from memory perhaps we want to compute something using them and To do this we have this axiom which says if our program is some value and one followed by an Operator op and then some value and two and we have some Store s then we can reduce this to some value n and the same store s if and is the result of applying this operator and to these two values and One and at two and this rule is called the op rule because it's for the Operator, so now you may wonder how do we actually get to the state where we have these values In our program well in order to do this we may have to evaluate some more complex expressions and to do this we'll have two Rules here one for evaluating the left-hand side and one for evaluating the right-hand side of a complex expression So let's say we have an expression that looks like this So it's some expression e1 op and then some expression e2 Which given a store we would like to reduce Then we can reduce e1 to e1 prime Which for example could be just a value that this expression evaluates to and we leave e2 the way it is And we may actually update Our store while doing this And now this is not a rule because we can only do this under specific conditions and in this case the condition Is that there is some way to take this expression e1? Evaluated given the store s and then obtain e1 prime and store s prime So this rule is what I call op l for left-hand side of an operation note again that the Store can be updated here So we may go from s to s prime in the simple version of simp that we are using here in the lecture This can actually not happen. So s prime is always guaranteed to be the same as s But in a slightly more general case where we may have expressions with side effects the store may actually be updated Now for the right-hand side of an expression. We can have a very similar Rule here, which now says if you already have evaluated the left-hand side So we have some value and one here followed by op and then some expression e2 Then we can reduce this to and one op e2 prime with a potentially updated store if There is a way to get from e2 and store s to e2 prime and store s prime and analogous to The op left name for the previous rule This is going to be called op r for the right-hand side of the operation So now you've seen these rules and axioms for defining the semantics of expressions in simp if you compare them to the Transition rules that we have defined for the abstract machine you'll see that they are a little bit simpler and you'll need fewer rules to actually evaluate an expression simply because we do not have these syntactic manipulations but actually always perform a computation whenever we are applying one of these transition rules and Now next we want to also look into the rules and axioms that we'll need to define the semantics of commands in simp So let's get started with an axiom that tells us how to handle assignments. So if we have An assignment that looks like this So we say that we want to write into some location the value n and we do this while having some initial store s Then we can reduce this to The following where our program afterwards just says skip. So we're basically reducing away this assignment and In turn, we are updating our store by now saying that the store is the same as before But now l maps to n So this rule is called the assignment rule and essentially what it is doing here is to update The piece of memory at location l Which is exactly what you would expect an assignment to do Now in order to get into a situation where you can actually use this assignment rule We may have to first evaluate the expression that is on the right-hand side of this assignment So we will have a situation that looks like this where our program is an Assignment into location l and the right-hand side is some complex expression e Now what should we do here? So this is what I'm going to show in this rule so we can conclude that this can be reduced to L gets assigned e prime with a possibly updated store s prime if There is a transition that goes from e and store s to e prime and the updated store s prime and this rule is called the right-hand side of assignment rule in the first rule you've seen that Evaluating this or executing this assignment that leads to the skip command So let's just have a look at what we can do with this skip command in order to get rid of it We are defining this axiom, which is basically saying if you have skip followed by some other command C and We see this using some store s then we can just remove the skip and keep the Remaining command C without really changing the store s so this rule is called skip and then another kind of Boring rule is for chaining two commands. So if you have Something that looks like this some command C1 semicolon C2 and we are now executing this given some store s then if we can say that C1 executed in s leads to C1 prime which updates the store s to s prime then we can execute This entire sequence of commands by replacing C1 by C1 prime followed by C2 and Updating this store s so essentially that gives us a way to execute the first out of two commands for example using the assignment Rule that we've seen above and then eventually once this is reduced to skip we can get rid of it using the skip rule and This last rule here is called a sequence rule because it's handling sequences of commands So now that two commands left in our simple language that we still need to define the semantics for and these are if and While commands so let's get started with if and then we'll actually see a quite elegant trick to define while commands The very little effort. So if you have an if There are again these cases where we have true and false in our condition. So let's start with the true case where We have something like if true Then C1 else C2 and we want to Reduce this given some stores Then we can reduce this by simply saying oh now we execute C1 and forget about all the rest and Distort stays the way it is. So this is the If rule for the true case and Then very similarly we have also the same for the false case So if you have an if and we already know that the boolean condition evaluates to false Then this is reduced to just taking the false branch. I'm sorry the DL's branch C2 and And then in the next step afterwards you can evaluate that command C2 So this is the if rule for the false branch So now you may wonder how do we actually get to this if true or if false and The answer is that we of course first have to evaluate the boolean expression. So let's have a look at how we do this So if you have an arbitrary if statement that does not yet have its boolean expression evaluated It's something like this if B then C1 else C2 And let's say we are Reasoning about this given an initial store s that we need to have Some way to reduce this boolean expression where we take the boolean expression and the initial store and if we are able to reduce it to some B prime which for example could be true or false and In general this may have an effect on the store. So afterwards it may be S prime then we can also Replace this boolean expression in our entire if command So instead of B we now here have B prime for example true or false and the rest stays the same And of course because we have changed potentially changed the store into S prime We also need to change it here So this rule is called the if rule And now finally we also need to define the semantics of wild statements And we'll do this in a way that reuses what we have said about if statements above as follows so if you have a wild command like this wild some boolean expression B do C And this is going to be evaluated with store S Then we actually can rewrite this into an if statement which contains a while loop inside where we just say if B so if this boolean expression is true then First execute the body of the loop and then we sequence this with another command Namely a wild command again where we have the same while B do C loop So we're essentially saying Well, what the semantics of a while loop actually is so if the boolean condition is true then evaluate The body of the loop once and then go again to the beginning of the loop and see what happens next And if the boolean expression is not true, then we are not going to do anything So we just replace or we just put here as dl branch our skip command and this is in a sense just a syntactic trick But it saves us the effort of writing down rules that most specifically say what a while loops are about because we can express it Very simple in a very simple way just like this Let's make all of this a bit more concrete by looking at an example And this example is a program that we've seen earlier. It's a program that basically swaps two variables the values of two variables using some temporary variable. So we have this variable z Which will get the value of x And then we have two more commands here one that writes the value of y into x And then one that takes the temporary the value of the temporary variable z and writes It's yeah, this value into y and now let's say we want to evaluate this program Given an initial store where z is zero x is one And y is two Then in order to do this we need to find a sequence of transitions where we start with p and s and then Apply multiple transitions go through multiple configurations and eventually want to arrive at only the skip command And then we'll also see it updated store and because you Um understand what this program is about you'll also understand that in the updated store z will have the value one And the values of x and y are swapped. So x will have the value two And y will have the value one So now you may wonder well, what's actually in this dot dot dot because that in a sense is the most interesting part of here so each transition each step that we are taking here needs to be um Yeah shown to be valid using either an axiom that we are using Or by using some rule and in order to um Use one of these rules we'll actually Need to show the proof tree Which basically shows that the preconditions the hypothesis of the rule are also true for which we may need to use other rules Or maybe need to use an accept. Yes, sorry an axiom Now let's look at an Accept and that's where the word already came from Um of this proof tree And this will be the very first Um step that we are going to take here. So on this very first step Um, we look at the entire old program. So this will just be p as we have it given initially and s And this can be reduced into a program Where we are reading the value of x And we'll see that this is one And then the rest of the program Is just the same as before And the store doesn't change here. So this is the sequence Rule that we are using here But now in order to use this rule, we of course have to so if you go back Um to where this was defined. So if you want to use this rule, um, we also need to show something So we need to show that we can actually take the first command and reduce it the way we want to do it here And in order to do this for this example, what we'll need to do is to basically Reason about the right hand side of this assignment. So we somehow want to show that if we have z Getting the value of x With store s, then you can reduce this to z Getting the value one with store s And in order to do this, we are using the Rule for right hand sides of an assignment and now Going back to that rule So this is this one You see that in order to do this, we need to have something that tells us How to evaluate the expression on the right hand side to an expression e prime Which in this case means we need to have a rule that tells us that if you look up x in the store We'll get the value one and actually we do have a rule for this Which is saying well if you have a lookup of x given This store s that you see above Then this actually yields one and the store doesn't change and the rule that we can use here Or to be more precise the axiom is the one that we have looked at at the very beginning Which was the one for looking up the value of a variable Now this is just the very first step in this sequence of transitions and for each of these Transitions, we either need to just use an axiom Which is the simple case or need to show that we can actually use a rule and if we have To use a rule that we need to provide a proof tree like this to show that we can actually Take this transition So this sequence of transitions is called the evaluation sequence and let's have a look at What properties this evaluation sequence could have and what this actually means for the program that we are reasoning about here, so given a configuration ps We say that the evaluation sequence Is a uniquely defined sequence of transitions So uniquely defined here means that there's one only one way of actually Showing this transition or the sequence and this sequence of transition starts with this configuration p comma s and it has maximal length and What this means Is that we've applied all transitions that are possibly applicable using the axioms and rules that we've just defined, so we do not stop at some point When we still could continue, but instead we add transitions and perform transitions as long as we can And now if we do this there are three possible outcomes of the program the first possible outcome is that this Evaluation sequence turns out to be infinite And what this essentially means is that this program has for example in an infinite loop Or maybe if we had a language that also has functions We could also have a recursive function call that continues forever but in any case the term we'll use here is that the program is divergent Which is just um, yeah another way of saying that it's going to run forever Then the second possible outcome is that we have a finite sequence that Eventually reaches One of the good states that tell us about the final configuration or the result of this program So in this case, we have a finite sequence that reaches either a configuration n comma s so where we have some integer value or configuration b comma s where we have some boolean value or the configuration Skip comma s where we do not have any value, but we also don't have anything left to do And in this case we say that the program Terminates And we say that the final configuration that we get so one of these three configurations that you've just seen Is the result of the program And then there's a third case Which is that we do have a finite sequence But the sequence Stops at some other configuration. So it's not n comma s b comma s or skip comma s But some other configuration for example one where we try to still execute some command But for some reason we can't And in this case we are saying that the program is blocked Which essentially means that the program just can't continue to execute and we can't really say What the result of this program is because it's in some sense or another an invalid program So let's have a look at some examples for these three cases so that these three concepts of divergent Terminating and blocked programs become a bit more clear so An example for the first case where the program is diverging would be the following Let's say we have a program that says while true Do skip And now let's say we have some store s and want to Evaluate this program and reason about its semantics. Well, then what we'll do is we'll first use our rule for For while which says We replace this with an if followed by the boolean condition in this case true Then We take the loop body once so skip followed by the entire loop again so again while true Do skip And then we also an else branch where we put skip And now if we reduce this further in this case now by using our if true rule then we can reduce this to the if branch of this Yeah, the then branch of this if statement, which in this case would be skip followed by Our loop again. So while true Do skip And then as you can see this goes on and on and on and on so we can basically Continue forever applying our transition rules, but we will never terminate simply because this program has this infinite loop Because it says while true do something So this is an example of a program that we can Show to be divergent As a second example, let's look at this Case where the program is terminating. So that's the Typical behavior of a program that you would like to see because this means the program Finishes at some point and it has a result. So for example, let's say we have a sim program That says if four equals zero Then skip else skip So not a particularly useful program, but one that is short enough to just show here as an example So in this case, um, we will use one of our rules to actually show that this boolean expression evaluates to false So we will have if false Then skip at skip Which doesn't change the store and now we can use another rule which Is about the if false case Actually, that's an axiom Which means we can replace this if statement with the um else branch which in this case is skip Which leads us to skip and s and this was one of the possible um Result states that tell us that our program has actually terminated. So this second example Is an example of a program that is terminating And then finally, let's have a look at the third case. So a program that is blocked So there are different reasons why this could happen But one is what i want to show here where we have And if that says if the value of x is larger than zero Then perform some command c which for the example doesn't really matter. So let's just call it c as skip And now we are evaluating this given some store s Where actually this value x is not in the domain of our store s Which means the store doesn't really know what the value of x is because this label is not mapped to anything And then if you have um a program like this where we basically try to read some memory that is not defined in our store Then we can't really evaluate this program any further and this means this means our semantics Here are blocked and we can't really tell what the meaning of this program is All right, and that's already the end of Video number four in this lecture on operational semantics. So you've now seen Small step semantics, which is one of the two styles of structural operational semantics that we're looking at here And as you've seen you can use axioms and rules that tell you when to transition from one configuration to another To determine what the semantics of a program are and whether the program terminates or maybe is blocked or maybe Is divergent. Thank you very much for listening and see you next time