The next step, so our next speaker is Dankrad Feist. Dankrad is an Ethereum researcher with a background in theoretical physics and technology. Since joining the Ethereum Foundation in 2019, he has worked on topics involving applied cryptography, sharding, statelessness, the proof of custody and other related topics. His talk today is on data availability commitments with distributed reconstruction thanks to the ZKG commitments and how they were able to construct a unique data sharding solution that supports high data bandwidth while preserving security properties without requiring powerful actors beyond normal validators.  Okay, fantastic. So I'll hand it to you. Thank you. Try to share my slides here. Okay, we can see your screen. Okay, great. Cool, thanks for the introduction. Yep, so I'm going to talk about data availability commitments that allow distributed reconstruction and how we're able to do that using a two-day, two-dimensional KZG scheme. So as an outline, I will be talking about data availability sampling, how that works, the basic principle, the merkle tree-based construction that was first suggested in 2018. And then how we came across fraud-proofing constructions using KZG commitments. And then finally, how we improved them using a 2D scheme that also allows distributed reconstruction and gets rid of requirement dependencies on super nodes for everything except for liveness. Well, potentially you could even remove it for that. So let's talk about data availability something. The idea of data availability sampling is that we want to know that OFN data is available using only OFN work. So like this, well, what we basically want is we want to scale data availability. So we need to somehow do less than OFN work in order to ensure this. And the basic idea is, well, what if we distribute the data into N chunks and each node selects K random chunks and downloads these and uses that to check whether the data is available. And so the basic problem with that idea is that, well, what if one of the chunks that you aren't checking for is missing, right? So in some applications that might not be such a big problem, you might be okay if 99.9% of the data is available but in blockchains because we have these applications where, for example, one single transaction could print a billion ether. That's not sufficient. Like we really need to be sure that all the data is available. Otherwise we can't use it. And so in order to be able to use this technique, we need to make it more powerful using something that's called erasure coding. Erasure coding means that we take our original data and we extend it. For example, using a polynomial. So what we can do is if we have these four data points on the left, we can always put a polynomial of degree three through them and evaluate it at a number of additional places. For example, four more places in order to double the original data. And then with a property that any polynomial of degree three can be, is fully determined by four evaluations. We know that if you know any four of these eight samples, you can get the full data. You got, you know everything about this polynomial and can thus compute all of the eight samples. This is called the Reed-Solomon code. And in this example, the coding rate is 0.5 because we extended it by a factor of two. And if we do this, then the sampling that we described earlier becomes efficient because before we had no way of using sampling we had no way of using sampling to efficiently make sure that all the data is available. So we would have like in order to catch a single missing one with like a high probability, we would have to sample. Like for example, if you wanted 99% probability, we would have to sample 99% of the data. So that's not efficient. But once we do this, it becomes different. So if you wanted to hide any data here, you would have to provide less than 50% of all the samples as an attacker. And in that case, if you, for example, do 30 random samples, then the probability that all of these passes only to do the minus 30. So that's great. The radar coding can make data will be sampling efficient, but now we have another problem. Now we need to ensure that this coding is correct because if the coding is incorrect, basically what could happen is that an attacker just instead of providing here in this example, eight correctly encoded samples, they could just provide random samples. And then each four of these would not give you back the same polynomial, but each would give a different polynomial. And then clearly, yeah, like your sampling doesn't help because you still don't know what exactly the original data is unless you get the original data itself. So there are mainly three possible approaches to ensuring the correctness of an erasure code. You can use frog proofs. You can prove that an encoding is correct. They sort of like, well, naive way using a snark. And then variants C is actually similar to B is uses polynomial commitment, which is also a form of proving that is correct, but it uses more natively the cryptography and therefore becomes much more efficient as we're going to see. So using frog proofs, basically let's assume that we commit to this data availability route, which is basically Merkle route of our data samples. Then what would be required for a frog proof, like let's say these are not all on the same low degree polynomial, we need at least degree plus two pieces to construct a frog proof, right? In order to prove that they are not all on this polynomial, we need enough pieces to reconstruct the polynomial with just degree plus one, and then another one so that the node can see, oh, no, like it's not all on one polynomial. And so the frog proof would, in this case, in this naive way be the same size as the data block. So that's pretty terrible because now like the worst case actually stays the same as it originally was, you still have to send the whole data. So that's not practical for our application. We would only get an average case reduction in the efficiency, increasing the efficiency, but so here's an example of this. So you would need, for example, to give these five pieces in our example in order to prove that it's not on a low degree polynomial. And the solution to that is to instead use two decodes. So basically what you do is you encode the data into a two-dimensional polynomial. And what this means is that each row and each column in itself is a one-dimensional polynomial of low degree. And this is nice because that means if there's any incorrect encoding anywhere, then you can prove this by just giving either the row or the column where the mistake happened. And so the fraud proofs now become root, order of root n of the data size instead of order of n. And this was basically the first practical, practically efficient data availability scheme. And it's also nice because it still only uses hash functions. So all this can be constructed using Merkel trees. And this construction was proposed by Alba Samsonino in between in 2018. The coding efficiency of 2D schemes is a bit lower. And that is because if we extend by a factor of two, so we keep the same coding rate per row and column as we had before of 0.5, then the data actually comes extended by a factor of four. But we still require three quarters. Well, we actually, it's more. We now require three quarters of data to guarantee that all the data can be reconstructed. So basically, if you imagine if I am trying to hide data, then what I could do is I could, I would hide a little bit more than one of these squares, like for example, the lower right square. If I just hide a little bit more than that, then you wouldn't be able to reconstruct the data because each row and each column would be missing a little bit more than 50%. So it would not be reconstructable. So we need three quarters to be sure that it's all available. And so if we compare that to the 1D scheme, then that extends by a factor of two and requires one half for reconstruction. So it's more efficient in the amount of data that you have to put on the network. But the main downside of this ASB-18 scheme is that it actually requires fault proofs to verify the consensus correctness. So that means that we like, we don't, since we don't know that an encoding is correct by just looking at the root, it means that we need to wait for fraud proofs before we are able to be sure that a chain is correct. And that's a bit impractical for consensus nodes, i.e. the stakers who construct the chain because if they always had to wait for fraud proofs, well, you could construct a chain like that but you would be waiting at least several minutes or so each time because it could take a little bit longer for fraud proof to arrive and you really want to be sure there isn't one. So it would be a very, very slow chain. That's not really what we want. So instead, anyone who uses this design is probably going to make a different decision which is in practice, I think what Celestia is doing where relying on this design is that you will use super nodes for the consensus nodes. So you require all those who actually participate in the consensus by constructing the chain to be not just sampling the data but downloading full data so that they are sure that there is no fraud because if you don't load all the samples then you know that it's correct. This is not a practical solution for the Ethereum design because what we are really keen to have is that the consensus can remain distributed so that all that staking can run like say a Raspberry Pi at home that cannot process these amounts of data. For example, because it's also just relying on a much smaller internet connection than would be required for this. Okay, so the next idea for what you could do in order to get this sort of the fraud proof problem is that you could take a Merkur route of an encoding and instead of using a fraud proof to ensure it's correctness you construct a full snark that shows that this encoding is correct. But doing this the naive way is very expensive and one way to somewhat alleviate that is to use modern smart snark friendly arithmetic hashers but we aren't really confident in them yet. They're not really that well proven so currently we wouldn't really know what's exact function with what parameters to use so that we could be confident then in 10, 20 years that is still a safe function. If we instead just use well proven hash functions then it would be very expensive. In either way it would be like sort of pretty big data center like operation to compute these routes and so we don't really consider this practical at the moment. But what has now become practical is a third option which is directly using polynomial commitment schemes on which these snarks are built. So for example, a commitment scheme like KZT-10 allows us to directly commit to a polynomial which is in other words a read Solomon code and the correctness is actually enforced by the commitment scheme. And that's orders of magnitude faster than using a general purpose snark on a Merkle route. So the KZT commitment scheme takes a polynomial defined here by f of x and you can based on that you can compute a commitment to that polynomial. And for any evaluation y equals f of z of that polynomial you can compute a prover using the data of the polynomial itself for the coefficients can compute a proof pi that proves that f of z equals y. So using this commitment c of f and the pi as well as the values y and z a verifier can confirm that indeed this f of z equals y. And c of f and pi are just elliptic curves elements. So for example, using BLS 12381 which we are using that's 48 bytes. So they are very nice and compact. And the way I use them as data availability routes you basically take points on this polynomial you now set like these samples as f of zero, f of one, f of two and so on. And then you compute the KZG route of that polynomial. And yeah, you can basically think of this as something similar to a Merkle route but it's always guaranteed to be on the same polynomial. In terms of efficiency so someone needs to compute all these samples and in particular they need to compute their KZG proofs because the sample is only valid if you have the corresponding KZG proof. This is a lot more expensive than a Merkle proof and naively it would take O of n work to compute one such proof like you always need to touch unlike a Merkle proof where you only need to touch like log n elements if you naively compute a KZG proof you need to touch all the elements or all the coefficients of the polynomial. And so if you did that for all the proofs it would be O of n squared and that clearly wouldn't be practical but luckily we came across a technique that Dimitri Kovratovic together with me developed in 2020 which allows using FFTs in the group as to compute all these proofs in n log n time and that makes it practical to use this as a data availability scheme and compute all the proofs. Now if we use this in the way that we've described as a commitment scheme for one polynomial then we need to consider one further thing which is the reconstruction. So if less than all the samples are available we always need to reconstruct the polynomial so that we can get all the samples if it's possible. And I mean that's for two reasons one is like we need the original data so applications or like the whether it's executing the chain or rollups they will of course need the actual data so if some data is in the original data I'm missing we clearly need to reconstruct that in order to have the data but from a consensus point of view more important is the convergence property. So like we want clearly that all nodes should eventually agree whether a block is available or not because this is one of our additional validity conditions now. And so we need that all nodes will come to the same conclusion so either less than our thresholds like less than three quarters are available in which case we don't know enough samples so that all nodes will agree on that but it could be that an attacker say makes a higher proportion of those available and in that case it would be there would be some nodes who think that it is available and some nodes will not see the data as available and this brings us to the problem with the 1D KCG scheme. So the reconstruction being able to reconstruct all the samples would still require super nodes. So it would require nodes that are able to download all the data and compute the individual proofs for all of them in order to distribute them. So that means that the reconstruction in the scheme requires super nodes and that means that in the absence of honest super nodes a malicious actor could split the chain. So this is where we come to the two dimensional KCG scheme. So in a way this looks similar to what we had earlier with the original scheme that was proposed in 2018 using Merkle routes but instead now we commit to KCG routes for each row and those eight KCG commitments in this example themselves lie on a polynomial. So you can do a polynomial check on these and this now has the property that the rows and columns can be individually reconstructed. So like a node that wants to help in reconstructing all samples can download one row or one column and if more than 50% available it can get all the samples in that row or column and that way you can actually reconstruct the full square of data using only these nodes that process rows and columns. And so you can see the similarity to the Merkle route-based 2D scheme where our original motivation was to use the 2D scheme because we wanted to minimize the fraud proofs. And in this case we're not worried about the fraud proofs anymore because the KCG scheme guarantees correctness but we can now reconstruct in a distributed way which is another important property. We can actually even use this to construct the block in a distributed way. So we can also use this as a way to say there's actually nobody who needs to process all the data and compute all the proofs and all the extensions and all the KCG commitments for it because you can also do that by rows and columns because the nice property is even the KCG commitments can be extended. So you can just compute a polynomial extension on the data KCG commitments and get the extension KCG commitments below. And so that's also really cool property. So we can also support distributed block production which in my opinion is a little bit less important than distributed reconstruction but it's still a nice property to have. So the scheme was proposed by Vitalik Buterin in 2020. And so now basically what it achieves is that we require super nodes. Well, if we don't do distributed construction last point it only requires super nodes for liveness. If we do distributed construction then actually we can also theoretically construct a scheme that does not require super nodes for anything. And at the very least all the safety properties can be ensured by nodes that can only process rows and columns. So yeah, as in conclusion I've made an overview here to show what basically the downsides and upsides of the different schemes are. So on the left we have the ASB-18 Merkur fraud proof based scheme. And in the middle I have any scheme that's basically a proven Merkur route. So either a snark on a Merkur route or a 1D KCG scheme. They have very similar properties. And on the right I have the relatively new 2D KCG scheme that allows distributed reconstruction. Yeah, and so like the basically the big additional thing that we get is that we can get a convergence property for distributed reconstruction. So the original scheme clearly also had this property since it was also 2D scheme. So that's not a complete new property. But unfortunately it requires super nodes in the consensus because otherwise the consensus would be dependent on fault proofs which would be problematic. Cool, so that is the end of my talk. Thank you and I'm open for any questions if there are any. Okay, thank you so much for your talk, Dankrat. If you have questions, now is a good time to ask them. Again, you can please ask them in text or raise your hands if you wanna speak. Keep in mind that if you do speak, you will be on the recording. So if you would rather that I read your question, just note that in the text. So far I see one question in Slack and I will read it out because Marko is having some tech issues. And the question from Marko is what is the super nodes? I might have missed it. And could you explain the difference between white nodes and super nodes? Right, so super nodes are any nodes that need to process all the data. So a super node would be a node that is able to process the full block data without doing something. So in terminology, you're right, I didn't define this before. So a light node would be one that only does data availability something. And in between, we would have nodes that don't load rows and columns, which is still much lower than a super node, but a bit more than what a light node would do, which only does some random something of the data. Okay, next we have a question from Andrei. Andrei, would you like to read your question while? Okay, my question was, how do you compute the public parameters for the KDG commitment? You mean the trusted setup? Yeah. Yeah, so yeah, we're currently in the process of arranging that. So like we are gonna have a trusted setup ceremony later this year, so that is in the works. The good thing is that we only need a very small trusted setup of like, I think the current design scheme only needs to the 12, we'll go a bit further in order to have some room for a future expansion, but maybe two to the 15 or something like that. And so it's gonna be a super small one and gonna be a super quick ceremony, so we can have lots of participants. How could you elaborate and why you need only a small trusted setup? A trusted setup? So the reason is that in the 2D KDG scheme, you only need commitments for one row basically, and so the rows are relatively small. So it's only like, for example, in the current design, a bit more than 4,000 field elements, so that's a very small trusted setup that you need in order to commit to that. Thank you, and I have one more question with me.  Okay, so there are different ways. So you could, so basically the way we're proposing it is to simply give like the individual commitments, like so you can simply, in the second dimension, you basically give a list of commitments. And so it's not in a way, it's not a 2D KDG commitment, it's a list of 1D KDG commitments. You could also directly use 2D KDG commitments, which would have, yeah, it would make something slightly smaller, but it would provide much less flexibility in terms of how you can distribute transactions and so on, so like this small overhead seems worth it to us.  This is small, I mean, isn't it square root of N? Sure, yeah. Okay, sorry, thank you. That's fair, okay, yeah. Okay, I have another question from Marco. Do you expect this to go into production and if so, do you have concrete plans for when? Yeah, so I mean, it's the current plan for Ethereum Sharding. So a first version that will use the same commitment scheme but we won't actually do sampling yet based on this, like sort of a traditional scheme, I think we'll go into production probably next year. So that's EAP 4844, which we're planning like in the next hard fork after Sharding, sorry, after the merge. And then, yes, I mean, I would say within hopefully one or two years after that, that we'll go into production on Ethereum. And we seem to have another question from Alfonso Alfonso. Yeah, really quick, I mean, we have a bunch of light notes on these data availability proofs. We would be able to recover the original data from these proofs. If I'm a light note and I just, I mean, the samples are out there, I would be able to recover the data as well. And I mean, traditional read Solomon Cody. Sorry, what is the question? So if I would be able to recover the original data from the proofs from the samples that are distributed from the samples, yeah, yeah. Yes, if you don't know enough samples, you can reconstruct the data. Yeah. Okay, as long as I have enough samples, I would be able to reconstruct the original data used for the proofs. That's right, that's right. So like traditional read Solomon, we would have the same properties with these commitments. Okay. That's right, yeah. I'm not seeing any other text questions if there is a question that you would still like to ask. Maybe just a quick question. Yes, go ahead, Juliana. Yeah, some very busy question, still early morning, yeah. So that's pretty much it, but can you go again over the very basic motivation behind those features that you presented, not how they're realized, why do we want them? Which one in particular do you mean? Just really basic, why would I want light nodes that can only, if I did the availability, but maybe not reconstruct the data or things like that. Right, I mean, well, that's the, oh, why do you want those light nodes? I mean, that's the core paradigm of scaling, right? We ultimately, like, if we want, like, what we want is we want blockchains that have the same properties as now, like right now, like, you cannot, like minus cannot construct an Ethereum chain that's not available, that has missing blocks because full nodes would just not accept them, right? And that is one of the properties that we want to preserve as we scale the chain. So we want to keep the same security properties as we have now, but be able to scale Ethereum. And so what we need for that is to come up with constructions that scale. And why would you want a light node, I guess is another possible point of your question. Why would you be interested in a light node that can only tell you, yes, this is the head of the chain, but cannot tell you what the data is, like for example, would not be able to construct the actual state because you can get your state somewhere else. Like for example, now you say you have this light node that tells you here is correct chip of the Ethereum chain. And now you could go to like someone else and ask, hey, can you give me the balance of my account or like whether this transaction has passed through? And they could give you a proof based on your latest state rule, right? So they couldn't cheat on you. They could give you like the data and they could add like a witness that shows that this data is correct based on the latest tip of the chain that your light node has provided you. Does that answer your question? Yeah, it helps, thanks. Okay, I think we still have time for one last question, if there are any. Have a small question about the motivation. So you had a part was the talk where you talked about the ability proof, but I'm not sure I quite understand what's the purpose of having the ability proof when doing security that the nodes can refuse to serve when the data is actually needed, the node can refuse to give it. So it can have it, but it can refuse to help reconstruct it when it's in it. Right, so I mean, I think the best way to see this is it's a gadget that prevents someone from withholding data. So yes, I agree, like we do require actors, like if, like say I'm a light node and I don't actually don't know the data, I will need to get the data from someone when I actually want to like find out something about the chain, right? Of course, that's true, but my assumption is that Ethereum data is interesting enough that there will always be people around who will provide that and do that for you. Maybe you have to pay them, but like it's possible. What we need to make sure is that these actors, even if there's only one honest one left among them, that they will get guaranteed access to this data, like that they are guaranteed to be able to download this data if they want to. And this is basically like it's a little bit like a proof of data publishing, maybe also a good name for this. Like basically whoever is constructing the chain, even if like the majority of consensus nodes is malicious, they cannot force others to accept this chain if they are trying to withhold the data. Does it make sense? I'm not sure how the sampling helps because there may be a node who has all the data and you sample it and you see that it has the data, but then when you want to reconstruct it, it refuses. Okay, so if only one person does the sampling, then it doesn't work. What you rely on is that there are lots of these light nodes that all do sampling. And now if the node tries to cheat, it could target you. If it knows who you are and knows your IP address, then it could give you all the samples, but nobody else does samples, and then it could trick you. But I mean this still requires like for an average person that would not happen because it requires that you overtake the whole consensus to make it vote for that. So basically this mass of samplers, they protect you because like in aggregate, they would get enough of these samples so that the data could be reconstructed. So after the sample, do they store it locally? Yes, you need to keep the samples that you've done around and provide them later if someone is trying to reconstruct as well. Okay, no, that makes sense. Okay, fantastic, perfect timing. We are exactly at time. Thank you so much, Dankrat, for your talk and for your comprehensive explanations.


Anchor started. We were obviously just locally a local company working in Melbourne and today we're really deeply multinational. You know we didn't go into business in effect to make money. We went into business for the excitement of it and because of the technology we wanted to demonstrate the technology. Anchor is now the world leader in our niche of CNC tool and cutter grinders and of course all our competition is wanting to knock us off our perch and so product development, customer support being number one in our field that's the biggest challenge. Our grinding machines are very very accurate machines very reliable and they're the machine of choice you know right through America through Europe, Asia, Japan, Korea. It's because of the software and the mechanics and the fine blend of the two together and that work in harmony. What I'm most excited about is the people we've got working for us, you know the talent of the young engineers, young salesman, young managers. It gives me confidence that we've got momentum and we'll be able to maintain that momentum.


When was the last time that you thought about attraction? Was it an hour ago? Five minutes? Ten seconds? It's likely that other people are thinking about it as much as you are. Here are seven psychological things we do that make us less attractive. 1. Acting cool and distant While procrastination might feel good, it isn't attractive. In 1992, two psychologists named Morlin and Beach were curious about the relationship between how many times you see someone and how attractive you find them. They had four women pretend to be students in a large intro psych class. At the end of the semester, students in the class were asked to rate how attractive they found each of the women. What the researchers found was that the fewer classes a woman attended, the less attractive they were rated by other students. The other students basically forgot about her. I'll try and remember this study the next time I have to psych myself up to go to class. 2. Acting clingy It's the classic young love phenomenon, constantly hanging out together. Three social psychologists from the University of California, San Diego, conducted a study on the relationship between people's physical proximity and how much they like each other. The researchers made a surprising discovery. They asked students to name who they liked and disliked. The researchers found that the students most like people were those who they frequently met face to face. But the researchers also found that the students least favorite people were those with whom they were forced to spend time. In other words, watch out that spending time with your crush doesn't end up with you getting on their nerves. 3.  Psychologists Curtis and Miller randomly paired participants. One student in the pair was led to believe that their partner either liked or disliked them. Those who thought they were liked were nicer and their partners ended up liking them more. The researchers concluded that so-called reciprocal liking is a self-fulfilling prophecy. If your partner thinks you like them, they'll be nicer to you, which in turn makes the whole relationship better. And the opposite is also true. If they think that you don't like them, they'll be meaner and the whole relationship will suffer. Turns out that grandma was onto something. 4. Revealing too much too soon In 2011, researchers told female undergrads that their Facebook profiles had been viewed by male students and that they would now be viewing the profiles of those guys. You can probably imagine that the women were intrigued. The women were split into groups and were told either that he liked their profile or that the researchers didn't know whether he liked their profile. The women were most attracted to the men who didn't reveal whether they liked the women. Why? The researchers decided that the more the women pondered the mysterious man, the more he was on their mind and the more intrigued they became. Austin Powers' nickname was actually pretty honest. The magical man of mystery does get the dates. 5. Going on boring dates Two psychologists in Vancouver, Canada, did a study on misattribution of arousal, which is when people make mistaken inferences about what is causing them to feel the way they do. They had an attractive female research assistant give male participants a questionnaire. In the first group, she asked them the questions while they were on a scary suspension bridge. In the second group, she asked them while on a low, small bridge. Those on the scary bridge were more excited because of the bridge and were more attracted to the research assistant and more likely to call her later. On your next date, don't just get coffee. That's boring. Instead, go see fireworks or ride go-karts. 6. Using cheesy pickup lines Psychologists who study attraction have identified three general strategies for pickup lines. Cute, flippant, for example, your place or mine. Inocuous, such as, what do you think of the music? And direct, as in, can I buy you lunch? A study asked men and women which pickup lines they prefer to receive. Most strategies work for men being approached by women. However, women tend to prefer innocuous and direct lines over cute, flippant ones. Bottom line, growners aren't attractive. So now you know. Asking someone, did it hurt when you fell from heaven? Is scientifically, the lame is possible thing to say. 7. Not having a wingman or wing woman Some people treat dating like a competition. But did you also know that there's lots of room for cooperation among friends? Having a third party make the introduction may be the best strategy of all for guys trying to pick up women. Especially in today's dating world, where there's more choice than ever, daters have to overcome many hurdles in order to catch someone's interest. Having someone make the introduction for you automatically moves you past the difficult first stage and it makes it clear that you're nice enough to have friends. Sorry James Bond, but in the real world, the best romancers work in pairs. In today's fast-paced dating world, people are quickly judged on first impressions. But don't worry, all you have to do is make sure you never do any of these seven unattractive things and you'll do fine. Although, bringing chocolates never hurts either.


Welcome to part 3 of the lectures on intermediate code generation. So, today we will continue to discuss the code generation strategies for various constructs. So, we briefly discussed short circuit evaluation of Boolean expressions in the last lecture. So, today let us consider in detail and see what difficulties it can actually give rise to. So, if there is an expression Boolean expression expression 1 and and expression 2 or expression 1 or expression 2, it is not necessary to evaluate the complete expression in all cases to know the value of the expression. For example, this is an AND operator if expression 1 is true then we must actually evaluate expression 2 in order to know the complete value of the expression. However, if expression 1 is false it is known that the entire value will be false it is not necessary to evaluate expression 2. So, similarly in this case if expression 1 is true it is not necessary to evaluate this complete expression at all it is necessary to evaluate expression 2 only if expression 1 is false. So, therefore, in the case of short circuit evaluation we try to evaluate only parts of the expression as necessary to infer the complete value you know the value of the complete expression. We do not really evaluate the entire expression in all cases and it is also possible to generate a control flow code for such short circuit evaluation as we will see very soon. And since such Boolean expressions are mostly used in conditional and loop statements we can always take advantage of the control flow representation of Boolean expressions. The advantage of this short circuit and control flow you know expression representation is that it is much faster than the normal evaluation. But the disadvantage is that if by chance the expression has some side effects for example, expression 2 has a function call or a print statement and this function call has alter some global variable. In such a case if expression 2 is never evaluated because the value of the entire expression was inferred using expression 1 then non deterministic behavior can arise. So, in some cases x 2 is not evaluated so the printing and other side effects should not take place. In some cases expression 2 will be evaluated and in these cases the printing will happen. So, such non deterministic behavior if it is not desirable then short circuit evaluation should not be performed. Here is a detailed example so we have an expression here and it is odd with another expression. So, in this case if the first expression is true we do not have to evaluate the second expression at all. So, the code here shows that so we do t 1 equal to a plus b t 2 equal to c plus d and if t 1 is less than t 2 we go directly to l 1 which is the code for a 1 that is the then part of the expression. So, we skip the evaluation of this entire expression but if t 1 less than t 2 is false then we have to go and evaluate the second expression so that is l 2 part. Again here we have and expression so if this is false we do not have to evaluate this part and if this is true we need to continue evaluation for this part as well. So, if e equal to f go to l 3 so that means we must evaluate h minus k otherwise we go to l 4 which is really the code for the l's part that is a 2 right here. So, this is how the short circuit evaluation and control for representation of Boolean expressions takes place. So, now let us understand how to generate such code so e going to even or e 2 so as usual we place a marker m here m really goes to epsilon and only remembers the quadruple number of the next quadruple to be generated. So, in this case it remembers the beginning of the code for e 2. So, if even is true then you know we do not have to evaluate e 2 at all. So, therefore, e dot true list which is very similar to the statement dot next in the case of statements. So, e dot true list becomes a merger of even dot true list and e 2 dot true list. So, there could be jumps out of this e 2 as well that is why we need to have two lists and merge them this is the exit part for the expression in case even is true. Then if even is false we must compulsorily evaluate e 2 therefore, it is logical to patch even dot false list to the beginning of e 2 which is m dot square and e dot false in this case will become e 2 dot false list because we come to e 2 only if even is really false. What about the AND operator very similar it is you know in some sense complementary to the R operator. So, if even is false the entire expression would be false. So, we have to take an exit. So, e dot false list is a merger of even dot false list and e 2 dot false list and if even is true we still continue and evaluate e 2. So, we back patch even dot true list to the beginning of e 2 which is nothing but m dot square and e dot true list would be obviously, e 2 dot true list because we come to e 2 only if even is true otherwise we do not even come to e 2. e going to not even we simply swap this true list becomes even dot false list and false list becomes even dot true list and we saw e m 2 epsilon already e going to even less than e 2. So, you must obviously, generate test here. So, generate even if even dot result less than e 2 dot result go to and then followed by a go to this is the false part and this is the true jump. So, that is why e dot true list takes on it this quadruple and e dot false list takes the next quadruple. So, these two lists contain these quadruples here e going to parenthize even parenthesis parenthesis expression. So, we just copy the list and nothing much happens and if e is the constant true just like numerics this is the Boolean constant true and this is the Boolean constant false. Then true list will take in itself this go to and in the case of false list e dot false list will take this particular go to statement. So, this is easy to see you know the use of this is very easy to see for example, you know if we have this if expression s 1. So, if e this is let us assume the constant true right. So, in that case e dot true list will be patched to next quad which is nothing but the beginning of the then statement and in this case e false e dot false list will be nil. So, nothing is patched here and similarly for e equal to false if this is false then you know we have to jump to the else part to the else part and that automatically is done later. So, let us go through this. So, s going to if x s 1 n else m s 2. So, if if x p is false if x dot false list is you know if the expression is false then it is patched to we need to jump to m dot pad which is the beginning of the else part. So, false list is patched to this and the exits from s would be the exits from s 1 and the exits from s 2 and also the jump here and the jump from n to epsilon generated during the reduction of n to epsilon. This we already saw if s going to if x s 1. So, the jumps out of s would be merger of s 1 dot next and if x dot false list these are the only ways to jump out of if then statement. So, now the while statement. So, here we must be you know we must observe in this case we must observe that for the r and and operators we really have not generated n any code. So, it is just that we direct the true list and false list appropriately. So, the actual code gets generated in a comparison all right and these quadruples will be patched appropriately in these productions. So, really speaking this is the comparison and go to are the only statements which we generated and that is why it is called as control flow representation or implementation of Boolean expressions. So, going to the while loop this is very similar to what we have seen already. So, while x do s 1. So, we need to jump we are here. So, we jump to the beginning of the while loop. So, we generate a go to to while x dot begin and all the jumps out of s 1 must go to while x dot begin. So, that is back patched here the only exit out of s would be when this expression is false. So, that is while x dot false list this is very simple. So, while x going to while m e. So, false list will become e dot false list that is the exit and true list will be patched to next quad which is nothing, but the beginning of s 1 because when the while when the expression is true we just fall through and execute the statement s 1 and while x dot begin would be the beginning of the expression m dot quad. So, m to epsilon of course, is the same as before. So, now let us proceed and look at the code generation mechanism for one of the most complicated programming language constructs the switch statement in C or a C like language. The syntax of the statement is switch and there is an expression. So, this expression must necessarily be producing integer types and then we have a list of values here l 1 l 2 1 l 2 2 etcetera etcetera and we also have a list of statements s l 1 s l 2 s l 3 etcetera.  So, if this expression is equal to this value at run time then the list of statements s l 1 is executed. If it is equal to l 2 1 or l 2 2 or any of these then s l 2 is executed etcetera and if none of them match then the default takes over and s l n will be executed. So, this code can be this switch statement can be compiled in many ways. One simple way would be an if then else like this you know an explicit if tests and so on and so forth. So, let us go through this and this is good for 10 to 15 cases. So, code for expression. So, the result is in temporary t. Now, we must why is this switch statement difficult for code generation. The problem is the expression is evaluated. So, code for generation code generation for expression is very simple straight forward. We really cannot generate a test for l 1 and then say let us go to s l 1 etcetera etcetera.  So, the reason for this is if all the tests are at the end after the statements are all generated code for statements is generated the compiler can possibly replace this entire set of if then statements by a more efficient implementation such as a table search or sometimes even you know maybe a hash table and things are with kind. So, after the code for expressions we have a go to. So, we directly go here and following that is the code for s l 1 s l 2 etcetera, but the control flow will bring us here. If we execute the test if t equal to l 1 then go to l 1. So, we execute the code for s l 1 if we wanted to execute only s l 1 and then jump to exit we should have had a break statement within s l 1 as a part of it. So, if there is no break statement in s l 1 automatically after s l 1 it will go to s l 2 and execute it this is known as fall through execution and the C language does not really prohibit this. So, a break statement must be compulsorily inserted here if we really want to get out of the switch statement after executing s l 1 the same is true for s l 2 etcetera up to s l n as well and after this we have the code for next which jumps to the exit. So, in the worst case if we start executing the code for s l 1 because t equal to l 1 is true and we have no breaks anywhere all these would be executed and then we go to the end of the switch. So, this is how the code generation must happen for the switch statement. So, let us see how it can be done. So, remember this order first the code for expression and then go to and then we have the code for s l 1 s l 2 etcetera, but in the meanwhile when we generate the code for s l 1 s l 2 etcetera we must remember the beginning addresses of these codes l 1 l 2 l n. So, that we can generate these if then statements at the end of this sequence of codes. So, if we do not know l 1 and if we have not remembered this then you know we will not be in a position to generate this statement at all. Our strategy would be generate the code for expression then as we as the parser scans this l 1 l 2 1 l 2 2 etcetera. It creates a list of these labels and along with it it also keeps track of the beginning of the corresponding statements. So, for l 1 it would keep the beginning of s l 1 as a pair and in the case of l 2 1 it will keep the beginning of s l 2 for l 2 2 again the beginning of s l 2 etcetera. And for the default it will remember separately the beginning of its block of statements s l n. So, this is our strategy for code generation. So, let us look at the grammar for the switch statement. So, here according to the C reference manual switch statement is one of the selection statements. So, selection statement can be switch followed by expression followed by statement. So, if this statement is not one of you know the case statements as we know then there is really no effect of the switch at all. So, there is nothing much you can do unless you have cases and the labels. So, that is why here is a more intuitive form of the switch statement which inherently has to be taken care of by any parser anyway. So, let us look at it statement is the switch statement I mean is a switch head followed by switch body. The switch head is the reserved word switch followed by the expression and E must be of the int type. The switch body has a pair of flower brackets followed by that is you know case list. So, the case list has a list of case statements and each case statement has a list of case labels followed by a statement list. The case labels can be empty or you know many case labels. So, each case label has the reserved word case followed by a constant integer expression. So, this must be either int or care type or it could be the reserved word default. One of the statements can be a break to ensure that the correct flow of statements happens. So, let us look at the productions and see how to generate code. So, switch head goes to switch followed by E. So, we have an attribute called switch head dot result and another attribute called switch head dot test. So, switch head dot result stores the address of the result of E. So, E dot result and switch head dot test stores the address of the next quadruple which is nothing but a go to statement. So, far if you observe our code template, we have generated the code for expression and we have generated a go to, but we still do not know the address test here. We will know that only at the end of the sequence of statements is you know at the end of the switch statement really speaking. So, that is why we need to retain it on switch head dot test and we will patch it at a later point. If the statement is a break statement, then it is like the exit of the statement. So, statement dot next would take this on and next statement generated would be a go to. So, nothing else is done really. So, we generate a go to here. The reason why it is so simple to take care of a break statement within a switch is that we do nothing but getting out of the switch statement. So, it can be put on statement dot next. We are going to see later that for loops the handling breaks is not so trivial it requires much more machinery. What is a case label? It has a case followed by an integer constant integer expression. So, we keep the value of the constant integer expression which is available in constant index to dot val, keep it in case label dot val and obviously, this is not a default case. So, default is set as false. If it is a default, then we say case label dot default equal to true. So, now we go on generating many case labels. So, if this goes to epsilon, then we simply set it at false and put a null list on case labels dot list. If we are generating many case labels well you know if case label dot default this one is not true. In other words this is not a default case, then case labels dot list is got by appending case labels dot 1 case labels 1 dot list followed by case label dot val. So, if it is default we have to maintain it separately that is why we are doing all this. So, if it is not a default then we add this case label value to this case labels dot list along with the other one case labels 1 dot list. So, this is the list of labels that we are maintaining. We still have not really placed the beginning of these statements I know paired them we have still not paired it with these values we will do that very soon. So, if case labels dot default or case labels 1 dot default or case label dot default is true, then there is a default among these. So, case label dot default is set to true. So, case statement goes to case labels m statement list. So, we have taken care of all the case labels here. Now we get the statement list and it is beginning is remembered in m dot quad. So, case statement dot next is statement list dot next. So, that is the exit out of the statement list case statement lot list is obtained by executing ad jump target to case labels dot list with m dot quad. So, what we are doing here is to take the address of the beginning of the statement list which is available in m dot quad attach it to all the values on this case labels dot list and make that the case s t dot you know list. So, now we have a list of labels and list of associated statement addresses as well. So, at the end of the switch statement we can generate the if then tests. So, if case labels this is a default statement then we set it as m dot if m dot quad because for this again we need to jump to the beginning of statement is otherwise we set it as minus 1. So, case list generates a list of case statements. So, this is nothing but transfer of all the attributes here there is nothing more to it than that. So, this is now for so far we have generated this expression you have generated this test go to and then we have generated all the code for s l 1 s l 2 s l n. We have in we remembered the beginnings of these codes and we have also remembered the values l 1 l 2 1 l 2 2 l n minus 1 paired it with l 1 l 2 l n. So far this is the work done. So, now again we have a transfer of attributes case list goes to case list 1 case list case statement. So, we merge the two next and put it on this merge the two lists and put it on case list and default is set appropriately depending on whether this is the default or this is the default. So, now the switch body is nothing but case list. So, we have generated code for all this. So, we must generate code for go to next and then the these tests this is what remains. So, switch body is completed. So, we generate a go to here switch body dot next would be merger of case list dot next and then the next quad which is nothing but the go to here and for the other two it is just a transfer of attributes. What remains is the generation of the if then statements at the end of the switch. So, now we come to statement going to switch head switch body. So, we have all the lists with switch you know the expression etcetera is all here. So, switch head dot result contains the you know address of the temporary which maintains the result and in switch body we have the entire list of values and pairs. So, back patch switch head dot test to next quad. So, this is the test go to we had generated at the end of switch head. So, that must that go to next quad which is nothing but the beginning of the series of tests. Now, we iterate through the switch body dot list. So, for each value jump pair in switch body dot list v comma j equal to you know the next value comma jump pair from switch body dot list. So, we take the next value pair value jump pair assign it to v comma j. Now, generate if switch head dot result equal to v go to j. So, for each value jump pair we generate this. So, automatically we would have generated something like this. So, all these tests would have been generated at the end if there is a if there was a default you know within the list then we generate go to switch body dot default. If there is not any we simply add the switch statement dot next equal to you know we do not generate any of this and simply says a statement dot next equal to switch body dot next nothing else is done. So, the list of tests and the last you know default are both taken care of in this set of in this particular production. So, that completes the switch statement. Now, the next very important statement is the for loop in C. The for loop in C is a very general for loop. So, here is a the for then we have 3 expressions expression 1 expression 2 and expression 3 followed by a statement. So, here the all or any one or all of the 3 expressions can be missing the manual says. So, you know so you could simply have for semicolon semicolon statement. So, in that case the statement keeps running forever. Otherwise the this for statement is equivalent to these 2 together expression 1 is the initialization. So, it is executed first and then the expression 2 part is the test part. So, there is a while loop expression 2 then we execute the statement followed by expression 3 which corresponds to the increment in general. So, statement followed by expression 3. So, this while loop is repeatedly executed until expression 2 becomes 0. So, the code generation becomes a bit difficult why if you look at this equivalence we have expression 2 expression 1 no problem we can generate the code for that followed by that is the expression 2 we can generate the code for expression 2 also no problem at all. But then we have statement and then expression 3. So, whereas in the source we have expression 3 followed by statement. So, because of this the code generation becomes little more difficult we need to introduce extra jump statements. And all this happens because we want to generate code in one pass during L R parsing. Suppose we did not have to do that we had the parse tree already and this intermediate code was being generated by a a walk over the parse tree. Then you know we would have had the for statement to node having expression 1 expression 2 expression 3 and expression 4 as children. So, we could have visited them in the order expression 1 expression 2 statement and then expression 3 and generated code appropriately, but in one pass bottom up parsing we really cannot do that. So, here is the code template for the c for loop for even semicolon e 2 semicolon e 3 s. So, code for even and then the code for e 2 let us say the result is in the temporary t. And then we need to have a go to go to l 4 why we need to actually generate a test if t equal to 0 then something that is where the go to takes you. Then we have the code for e 3 right.  So, let us look at the flow of control. So, this is executed first this is executed next then we go to l 4 execute the test if t equal to 0 go to l 5 l 5 would be the exit part.  So, because of the order in which we need to generate code and the order that we need to generate code is exactly the order in which the source code appears. We interspers the code with go to statements in order to get the appropriate flow of control. So, here is our production statement going to for even semicolon m e 2 semicolon n e 3 followed by p s t m t 1. We have a couple of markers m n and p. So, as usual m does not generate code it simply remembers the beginning of the expression e 2. Obviously, that is necessary because we need to jump to the beginning of e 2 and evaluate it after the entire statement sequences executed. So, n generates a go to and p also generates a go to let us see how what kind of code is generated. So, in bottom up parsing we would have parsed this entire thing and generated code for even e 2 e 3 then m n p and statement 1 and we have we will be here just before reduction we need to execute this action. So, what does that action do? So, we have executed statement 1 now it generate there is a code go to n dot quad plus 1. So, n dot quad is the you know go to statement here. So, plus 1 would be the beginning of e 3 so that is correct right. So, we have you know we go to so this after the statement 1 is completed we are here right code for s is over. So, we go to the beginning of e 3 so right go to l 2 that is the beginning of e 3 that is where we are going. So, n dot quad plus 1 is the beginning of e 3 that is where we jump. Next q 1 remembers this quadruple so what is this quadruple? We have a test if e 2 dot result equal to 0 go to something. So, automatically we would have jump to this place and we will see from where we jump to just assume that q 1 remembers this go to statement and that is also according to what we wanted. So, here is this go to that we generated just now and here is the comparison that we have generated. Now, we need to generate another go to so now go to p dot quad plus 1.  So, if the result is greater than or 0 or less than 0 whatever what it is definitely not equal to 0 then we jump to the beginning of the statement that is what we wanted here. So, go to l 3 so beginning of core for s. So, far we have justified the generation of these 3 codes, but we have still not filled up this. Now, we back patch n dot quad with q 1. So, what is n dot quad? n dot quad is this go to statement and so that would be filled with q 1. So, we have evaluated e 2 now this go to takes you to the beginning of q 1 is nothing but this quad. So, this n the go to in n takes you here so which is correct again. So, we can see that after this e 2 we have jump to l 4 which is nothing but the test for t. Then we back patch statement 1 dot next with n dot quad plus 1. So, statement 1 dot next is all the jumps out all the jumps out of statement 1. So, that is patch to the beginning of e 3 n dot quad plus 1 is the beginning of e 3. So, we must execute e 3. So, this jump this back patch is also correct. Then we have back patch p dot quad and m dot quad. So, p dot quad is this go to which is generated here and that is to the beginning of e 2 again. So, at the end of e 3 we have go to to l 1 so the code for e 2 is executed all over again. So, then of course, statement dot next is nothing but the jump out of this when e dot result equal to 0. So, let us make list q So, this is the justification for this code generation for the for loop in c. So, there are other varieties of for loop in other programming languages. So, let us take one variant which is very popular this is the algal for loop this is also available in part of it partially it is available in Pascal as well. So, let us also look at this now that the syntax is statement going to for i d equal to expression 1 to expression 2 by expression 3 do statement 1. So, expression 1 2 and 3 are all arithmetic statements. So, what we really do is this we assume that this is the beginning value of i d this is the name i d this is the ending value of the name and this is the increment. So, we start with this value run the loop and every time we check whether we have reached expression 2 and we increment or decrement based on the value of x 3 and then execute the statement 1 if necessary. So, x 3 can have either positive or negative value. So, if the value of x 3 is positive then you know the expression will be lower than expression 2 usually we rise from expression 1 to expression 2 in a monotonically increasing order and if expression 3 has a negative value then usually expression 1 is higher and expression 2 is lower. So, we go down from expression 1 to expression 2 in monotonically decreasing order and then enduring this course we execute this statement. Another important thing is expression 1 2 and 3 are all evaluated only once whereas, in the case of C loop the expression 2 and expression 3 were evaluated every time in every iteration of the loop. So, this does not happen in the all go loop they are executed only once and the values are stored. Finally, all the three expressions are mandatory it is not that you can skip any one or more of them. So, what is the code template? So, you have a for i d equal to expression 1 to expression 2 by expression 3 do statement 1. So, we have the code for expression 1 result in T 2 code for expression 3 result in T 3. So, that is in the same order no problem at all in that now we have the statement 1. So, before that we have a jump. So, and then we have the code for statement 1 then the increment i d equal to i d plus T 3 and then finally, go to L 2 which checks whether the value of T 3 is less than or equal to 0. So, or it is greater than 0. So, the reason is T 3 could be positive or negative and based on that value the termination condition will also be different. So, let us then there are two tests one for a positive increment and other for the negative increment and finally, we go back to go to L 0 execute the statement and repeat. So, let us look at the flow of control here first of all the control executes and evaluates all the three expressions. Then we go to L 1 this is an initialization for the name i d then we check whether the increment is negative. So, if so we go to L 3 if the increment is negative then we check whether i d is less than T 2 that means, if it is less than then we need to jump out of the loop we have finished the loop. Otherwise, go to L 0 code for statement 1 is executed then the increment is added and we go back to the test again. Similarly, if the increment was positive we check whether i d greater than T 2 and jump out if it is greater otherwise we go back to L 0 execute the statement 1 etcetera. So, how does the code get generated in syntax redacted translation. So, we have statement then for i d equal to expression 1 to expression 2 by expression 3 we do not need markers among these simply because there is no need to jump to the beginning or end of any of these expressions they are evaluated only once. But, we definitely require a marker to remember the beginning of the statement and also to generate go to at the end of expression 3. So, remember there is a go to at the end of expression 3. So, m remembers the quadruple which is nothing but a go to here. Now, the name i d is searched for in the symbol table and we generate the increment. So, we are here we have finished statement code generation for statement 1 also. Now, we generate the increment statement and also a jump. So, we generate the increment statement then we remember this q 1 which is the next quad generate a jump here. Then since we had generated a go to here in the marker m and now we know where to patch that. So, for example, here this is the go to generated by the marker and that is to go to the initialization statement i d equal to t 1. So far we have generated all these codes we are yet to generate this. So, we generate i d p t r equal to expression 1 dot result and this is the quad to which m dot quad was backpatched. So, the go to has been now patched that go to has been patched properly. Next we patch backpatch q 1 with next quad and remember next q 2 as next quad as well. So, what is the next quadruple this is the test if expression 3 dot result less than or equal to 0 go to. So, for example, we have generated this. So, we are generating t 3 less than or equal to 0 go to. So, that is what we are generating and we have patched q 1 which is nothing, but this go to to come here. So, remember after the increment statement the go to supposed to go to the test. So, that is what we had done here. So, increment and then go to l 2 that is the test part. Now, if it is not less than or equal to 0 then it means it is a positive increment. So, we check whether i d p t r greater than expression dot result go to and then this is yet to this is the exit part this will go on to the statement dot next. So, you can see that. So, q 2 this is q 2 this is q 2 plus 1. So, we have put q 2 plus 1 also on statement dot next then after this if the exit is not going to take this we generate a go to to the beginning of m you know the statement which is nothing, but m dot quad plus 1. So, m dot quad is this. So, m dot quad plus 1 is statement 1. So, we generate that go to here and we back patch q 2 which is nothing, but again this quadruple right and with the next quad. So, next quad is again the check whether the i d p t r x has gone beyond its limit in the case of the negative increment. So, that is what we have done here you know. So, we back patch that into this and finally, generate a go to to the beginning of the statement if we have not cross the limit. So, statement dot next contains q 2 plus 1 then q 3 which is this this is also an exit this is one exit this is the other exit statement 1 dot next would be the third possible exit. So, all these 3 exits are put on statement dot next. So, this is the code generation strategy for the algal for loop it is also possible to generate code for the algal for loop in a slightly different way, but this requires a little extra work. So, for example, generation of code for expression 1 expression 2 and expression 3 straight forward. So, that will not even worry about now we try to do the initialization of i d straight away here before we check whether the t 3 is less than equal to 0 or greater than equal to 0.  So, the order in which we have generated this code slightly different from the order in which we have generated code for the other one. So, this would be left as an exercise for students to do. So, the hint is we may have to break the production appropriately and insert more markers in order to generate this code properly. So, now it is also time to look at you know important aspects of checking the range overflow in arrays. So, let us look at an example. So, here is int b 10 20. So, 2 dimensional array and here is an assignment a equal to b of x 1 x 2. What we want to do is make sure that expression 1 is always less than 10 remember c arrays run from 0 to 9 and this part runs from 0 to 19. So, we want to make sure that x 1 is less than 10 strictly and x 2 is less than 20 strictly. If it is not we want to issue errors. So, the code generation generated code template would be something like this code for expression 1 resultant even no problem. Now, before generating the code for expression 2 we check whether t 1 is less than 10 if. So, go to l 1. So, this is normal course of action. If t 1 is equal to 10 or greater than 10 an error message error array overflow in dimension 1 is issued. T 1 is reset to the maximum value of dimension 1 which is 9 0 to 9 is the array index range. So, we set it to 9 something very similar happens for expression 2 code for expression 2 result in t 2. If t 2 is less than 20 it is normal course of action otherwise we issue the error array overflow in dimension 2 set maximum value of t 2 as 19 that is the maximum for the dimension 2 part and then we proceed. So, since we have set it to 9 and 19 there are no more errors, but the results that we obtain by the computation may be wrong, but at least the program will try to execute to completion even though it may not produce the right value. So, t 3 is equal to t 1 another option possible here is to just exit the program, but if we had exited here we would not have caught this error that is the reason why we have set it to maximum and then try to continue. So, then the it is normal code t 3 equal to t 1 star 20 and then t 4 equal to t 3 plus t 2 and. So, we multiplied by the number of elements in the second dimension then add the second dimension value the subscript value that is t 2 then multiplied by the element size. So, t 4 into int size finally, a equal to t 6 of t 5. So, this is the code that is generated. So, here is the you know syntax directed translation for it. So, these two are the same as before they have been reproduced here to just to set the context properly s going to l colon equal to e. So, this is the assignment. So, if l dot offset is null we generate simple id. So, it is a simple id. So, we generate l dot plus equal to e dot result otherwise we set generate an indexed assignment. So, the right hand side could be an array again. So, again we check whether it is an array or simple id if it is an array then we generate an indexed assignment once more. So, this is necessary as I already mentioned both left and right sides cannot be array assignments at the array expressions at the same time. Now, this part e list going to id bracket e. So, we search for the name id dot name and get its pointer then that pointer is transferred to e list dot array pointer the result of e is stored in e list dot result. The dimension number is set to 1 because this is the first expression in the subscript list we get the number of elements from the for the dimension 1 using this array pointer. Now, we generate the required quadruples if e dot result less than num go to q 1 plus 3. So, this is q 1 this is q 1 plus 1 this is q 1 plus 2 following that is the normal course of action. So, that is q 1 plus 3 otherwise generate the error and then set it to num element minus 1. So, this is the maximum for the dimension 1 the same thing happens for other dimensions as well. So, here is the list of subscripts that is being processed. So, e list going to e list 1 comma e. So, the same thing happens here we get the number of elements in the appropriate dimension e list 1 dot 1 generate the three codes check whether it is this then num element if. So, jump to the third expression otherwise generate an error message and set the maximum to num element minus 1 at the end of it we do the normal processing temp 1 is equal to e list 1 dot result star num element. So, that is the number of elements in this dimension e add the e dot result to it. So, now we are ready to go to the next level. So, this is how we process the expressions. So, now this is the ending production e list bracket. So, here we just multiplied by the element size and that is finally, the offset that we have generated for e list. So, we will stop the lecture here and continue with break and continuous statements in the next part of the lecture. Thank you.


Bah! What's up everybody? Once again, it's Brandman. Shine! And today's video is brought to you by SoziLad. Because Sozi was watching the XXXTENTACION 7 Tips for Success video and said this, leave something to be desired. Can you do a video on the 7th tip? It contradicts the high-release strategy a little bit. True! That's the very reason why you do not make strategies. Because if you make strategies, then you don't have a strategy. But that boy Sozi's question did make me think about the fact that there is another part to that question that I haven't discussed yet. So here it is. Yes, it does contradict. Don't do that. The second answer is, eh, it doesn't necessarily contradict itself. Here's an extreme case. The weekend dropped the trilogy, which was a lot of people's first introduction to do. That's 30 songs, but we all know how mysterious the weekend was when he first came out. Mystery is leaving something to be desired to the max. And 30 songs dropped at once is high-release org's strategy to the max. How was the weekend able to do that? Well, I'm kind of about to tell you, chill. There's technically three brands that artists have. You have in front of Curtain, you have behind the Curtain, and then you have life or personal, whichever one you want to call it. In front of the Curtain is basically artist, right? It's that first phase with that superficial level that most people see of artists. You see their performances, right? They're literally in front of a Curtain. The performance, think about the music. Think about any aesthetic or maybe movies that they're in. All of that in front of the Curtain giving product. Usually you can define it by being the product or a part of the product. And then you have behind the Curtain. Think about behind the Curtain almost as a job. Behind the Curtain is the professional version of the artist, how they deal with other professionals, maybe how they collaborate with other artists, how they move throughout the industry. In all of that behind the scenes stuff just weren't getting done, the production being made for in front of the Curtains. And of course, now you have personal slash life. That means the actual person. Who is this person? Not the artist. Who is the actual person? What are they like? How do they move? What are their interests? And even in the age of social media, this is the least seen side of artists, especially since we still kind of curate what we show people on social media. But people like Trans The Rapper and so many other people in general is just not chance.  So why does the fact that there are these three brands matter? Because each one can have its own strategy of sorts. While the weekend is dropping a high volume release of music, he can still curate a very mysterious personal brand because he's not high volume release in his front facing personality. Two different boxes. I think I left a side off of that one. He wasn't doing a lot of interviews, right? So he had a lot of music and people really got acclimated to him and his brand. But his actual personality, he's not really showing that. There's no high volume release where there's some artists who are always on social jumping around, just trying to get attention or just letting people into their world. I'll get to which one is the most important in a second, but I want to first emphasize that it's very important that you're at least aware of these boxes. Remember when Beyonce introduced Sasha Fierce to the world? She clearly stated that Sasha Fierce was somebody that she always had or saw herself as that box for in front of the curtain, because when she gets on stage, she becomes this different woman that is not Beyonce. So she just actually branded that front side of somebody separate, which could be pretty important mentally, literally for someone who is actually going by their real name at all times. And to ask which ones are most important, well, technically fans care about number one and number three the most. That's sure in front of the curtains and your personal life. That's what people really care about. They're not really thinking too much about that behind the scenes production type. So that's what people pretty much will spend a lot of time branding or deciding how they want to handle. But number two is actually extremely important as well, but it's just a long term thing that just can't really be controlled per se. Because of the fact that number two is really your brand, with your peers for the most part, that means whoever you're collaborating with, whether that's a videographer or an artist, another rapper, you can't really push that brand and promote it in one way, but what makes that even more potent than the other two is because then you can create testimonials, because if you handle yourself really great professionally, you have other artists, which are other credible people in the fans' eyes, talk about you in whatever the way that professional ran is important. Case in point, think about how many people talk about Tupac's work ethic. Everybody knows that guy had a crazy work ethic because people who were with him are always telling stories of his work ethic. Whatever brand you establish there does have a potential to make a strong impact on your brand overall. But just think of number two behind the curtains as the long term brand legacy impact because that's what turns people into legends.  And because of some of these questions that sparked this video, I want to end with the last word. Contradictions almost never exist past the surface. What we're usually experiencing is a lack of understanding or context. The funny part about that is because a lot of people are actually too lazy to think past the surface. Contradictions are one of the most commonly used devices to distract the public so you can control what they're thinking or get a different agenda done. Anyway, please share this guys if you think other people will find this helpful and you know what to do. Hit that subscribe button.


What's going on everyone? Sam here with Layton Sports Cards and I am ripping one box of 2022 Panini WWE Revolution for Daniel H. So good luck Daniel, see what we got in here. All right, so NBA, I'm Atlanta Hawks, NFL, my favorite team out in all the sports is the Baltimore Ravens, NHL, not the biggest fan, I root for the Caps, my girlfriend's a big Caps fan and I'm not like the biggest hockey fan in the world, so I'm just a Caps fan for her. And then I am Yankees for MLB. So I have like stories for the Ravens and the Hawks and I guess the Yankees, but it's a very random like assortment of teams. I've got Base Base, uh nice Batista on the Cosmic to 149, nice one there, get that to focus, there it is, nice Batista, Cosmic, solid, then we've got Shockwave, John Cena on the back, haha they made a card with nobody on it, funny, what about you Joe, where are your teams? Haha I don't think you've seen a mudcats hat, Base, Base got Groove, Rookie is Cora Jade, nice one there, and JBL on the back, the NHL comments stung a little bit, I like hockey, don't get me wrong Jeremiah, like I watched all of the cup, but I don't know, it's not like my number one sport, you know what I mean? Oh that's awesome, got, I think we have an auto in this pack, we got Astro, Rookie of Electro Lopez, got Vortex of Shotzi, got Base of Candice LeRae and Nash Carter, we got Auto is nice, Bianca Belair, that is Cubic to 49, that's five of 49 on the Belair, nice hit there, Daniel, congrats on that, yeah I'm a big, I love minor league hats, like minor league baseball hats, hang wire, so I had to pick up a mudcats one, I love the mudcats logo, that's pretty solid, so I'm assuming you're from like the Missouri area Joe, with the Cardinals in the blues, uh Waller, got Fractal of Candice LeRae and base on the back is D Generation X, Shawn Michaels and Triple H, yeah I love their logo dude, it's so funny, I might end up getting multi, I might get the white one too, and I think they have a black one, black with, I think it's black red brim logo and then they have white black brim logo, uh Virma Han, Ricochet, that's cool, that is the Stooges, Pat Patterson and Gerald Briscoe, that is Angular to 199 on that one, nice man, I've never been to Missouri, Supernova Brock Lesnar, never been to Missouri, I've never really been out that way, Cardinals, Dimebacks, Coyote Sons, I'm gonna guess probably the West Coast, Jeremiah, got Dakota Kai, John Cena base, nice, got Fractal of the Heart Foundation, Brent Hart and Jim Neidhart, or Neidhart, and the Rock and Sock Connection, the Rock and Mankind, nice one, oh that's where Hans, Hansborough went to school, that's where he lived, that's awesome, he was such a beast in college, it was like unfair, uh Indy Hartwell, Tony D'Angelo, Alexa Bliss, got Happy Corbin on the astral, and on the back we have Vortex of Oskar, or Oskar, that's uh 66 of 99, nice one there, it sounds like you're from Maine, yeah probably like North Dakota or something, Jeremiah, PB Meals, that's so cool dude, last pack, good luck here uh Daniel, base, oh yeah uh uh Rikishi on the astral, and last card is Undertaker on the base, it's gonna do it for your uh break there, Daniel, congrats on all the hits, get those right out, see you, thanks again man.


Stanley Howard-Watt says war is a great liturgical alternative to the Eucharist. The Eucharist being about Jesus on the cross who dies for enemies. The very thing that the prophets had in mind when swords would become plowshares. You see, the prophets have a better world in mind. Jesus has a better world in mind. A world that will be here when Jesus returns but it's a world that we're summoned into today. Gardening tools can be made of guns. Bombs can create hammers and nails and this is what raw tools is up to. Raw tools wants to create a better world in the midst of this one.


Scarlet and Violet have undoubtedly been the best games to shiny hunt in that we've ever seen and yes we've got a brand new method which could be classed as some sort of a glitch in today's video we're going to go through all the details to make sure you can take full advantage of this and get some more easy shinies in these games but before we get into today's video please subscribe to the channel remember you can always unsubscribe later if you would like to but like i say this new method was discovered a little while ago what you're going to need to do is head over to the east province area three this pokemon center here and we'll be heading to this area on your map so once you're at the pokemon center i want to just head this way and we are looking for an area with a little cave system in it okay and we want to come over to this area right here and there will be a cave right down here and this is the cave system where we're going to want to come into and you can see on your map this is where it is located just in case you didn't see initially and once you're in this cave you want to just head inside and you want to come like all the way down into this area and there'll be a trainer at the bottom and this is how you know you're in the right cabin we're going to get a bunch of different pokemon spawning in here you're going to get things like lava tar if you're in pokemon scarlet if you're in pokemon violet you're going to get a big one you're going to get a table eyes as well as salandits and a few other things glomora and stuff like that so when you're in this location you'll know this as well we've got three sableye there but if you notice where the next one spawns out in the wall they're kind of popping out the wall and this is a spawn point for specifically sableye lava tar if you've got pokemon scarlet or begon if you've got pokemon violet and this is the exploit that we're going to want to use this specific spawn point where they're popping out the wall and we're going to lay down a sandwich to make even better use of this to generate as many shinies as you want and it's going to be super easy to do so you want to set up your picnic and then come to make a sandwich now you can make it in whatever sandwich you want from whatever list we've got a bunch of different recipe lists we've got at the minute to make sparkling power with encounter power and that's all really you're going to want to concentrate on making sure that you think encounter power and the sparkling power for the specific pokemon that you're hunting if you're in pokemon scarlet you're going to want rock or ground for the lava tar and that encounter as well if you're in pokemon violet you're going to want the dragon which is for the begon with the encounter power or if you want to do something like sableye you can go for that dark or ghost encounter power and make sure that that's the only thing that spawns out so for this example we'll go for the sableye i'm going to pop on a ghost one and i'm going to use the recipe of two red onions green pepper red pepper yellow pepper and a prosecco and then i think we can use any combination of herbomistica see i'm running pretty low and that should give us the ghost encounter power and the sparkling power for ghost type and that is all we're looking for the encounter power and the sparkling power when we're shiny hunting so this is all done we've set a sandwich up we are ready to just kind of despawn our picnic area and then watch these shinies spawn in you want it you've got half an hour and you'll just see from this spot you're going to see these pokemon just jumping from the wall and this is all you're going to want to do you can just sit back and relax get on with something else if you want while these pokemon spawn in but if you do this you're going to bear in mind that you're going to get about 15 pokemon spawning and then they will stop spawning then you're going to have to set your picnic up despawn whatever's spawning and then just set a picnic up right now and then we'll just despawn the ones that are there and then we'll respawn some new ones in but just make sure that you are the right distance at the time you know if you're setting a picnic up and also moving around a bit you might change the spawns but you need to be in the exact position where they are popping out of the wall like a little sableye factory here you can see them all doing this but the other thing that you can do as well is use the let's go feature with your pokemon now there is a specific area in this tunnel where you can put your pokemon into let's go mode and they will just keep continually attacking these sableye or whichever pokemon that you're spawning in and they will literally find a void in the floor which will mean that they just continually use that let's go feature until you decide do you want to stop this going any further you know you've got half an hour with your sandwich par we've been doing this like maybe a couple of minutes now so we can either just continually use the let's go feature where it will just continually knock out these pokemon and more will spawn in over and over and over again like the little sableye factory that we've set up here until that shiny does appear so it's a really easy way to get a shiny but the other thing is if the zoomer all falls into this void in the floor area in this space it will continue to stay there will you'll have no worries about running back to you and then having to send it out again you can literally just let your pokemon just keep knocking these pokemon out until that shiny spawns and the nice thing about the let's go feature is they because your pokemon will never knock out a shiny pokemon you have got no worries about doing this like i'm just sitting here hands-free now while the zoomer all just goes to town on these sableye's hopefully like i say by just doing this a few times we do get a zoomer all stuck in that kind of void area of the cavern because it's hard to get to it when you've got so many spawns out in the cavern without initiating a battle with them so you kind of hoping most of the time that your pokemon will eventually venture a little bit further find the void get stuck in there and then the sableye are going to just spawn keep spawning out of this area and you kind of just need to if they're not spawning out of the area where you want them to or where that little area in the wall is just move your character around and then just that will ensure that the sableye keep popping out of the wall and like i say it's it's as simple as that you can use it with begon if you're in violet you can use it with larvatar if you're in scarlet and both copies can use it on the sableye sableye's an easy one to spot because it is that gold color has got quite a nice shiny now i probably prefer setting up a picnic rather than using the let's go feature because you're running backwards and forwards to set up the let's go pokemon if they don't find the void in the floor where they're stuck and that just causes a lot of like just interruption to this process whereas you can just stand here with your picnic and literally when they stop popping out of the wall the factory runs out like they are now we're not going to see any more you just want to set your picnic up and it's so easy just to sit here and do this and this is what i mean you're probably gonna get you're probably gonna be quicker to go through picnics than it is to just use the let's go feature and have your pokemon kind of knocking each one out as they come in and out of the of the wall there but you know it's entirely up to you if you want to combine this with using the let's go feature to get xp farming you're gonna get item drops obviously from every single pokemon that you knock out be it the larvatar the sableye or the begon then they can be sold for money as well so you're gonna be able to make a little bit of money back but i think overall the picnic method is probably quicker because we're literally seeing everything that spawns in here once they stop spawning in out of that wall we just hit the picnic it takes a couple of seconds just to get your picnic set up and then despawn it again and the process rolls over and you're gonna be able to really expedite this whole situation and get a shiny very quickly in these areas and there we go we got a fish shiny it did pop out the wall there you can see the little gold shiny just shining through and now we've got to run the gauntlet a little bit to try and get to it can use the let's go feature here to blast away them but the problem the problem is you're going to keep spawning more when you do use this let's go feature so we're going to have to try and see if we can maneuver our way around the sableye to try and get this shiny one and there we go so there we go shiny sableye love it love it so that is great that we've managed to get this one so quickly and if you've got duskballs it's a good idea to use them because we're in a cave system so you're going to have that increased chance to catch these pokemon which we're not going to get it the first time with this one and there we go a critical catch finally took a few duskballs i advise duskballs and of course it takes me about 10 duskballs to get the sableye use whatever ball you want right once your shiny is caught you can check to see how long of your sparkling power you've got left we've only got four minutes so we've not got very much longer we've been doing this i thought we'd get maybe more than one shiny from this but we haven't been able to so you can just repeat the process for the remaining you've got left and hopefully you can get more than one shiny doing this method like i say all you need to really do is be in the right spot to make sure that you are seeing these pokemon spawn out of the wall like they are here either use the picnic method or the let's go method to just knock these out or despawn them get them back respawning after you've done that method and then just sit and wait for your shiny while your sparkling power is active and then if the shiny doesn't appear in this first batch just repeat the method again and do it until your sparkling power ends and in that time you're bound to get a shiny because of the amount of pokemon that are kind of spawning in and out in such a short period of time with the higher shiny odds attached obviously if you've got the shiny charm you're going to get even more increased odds of the shiny spawning in the sparkling power alone is probably enough for you just to do this method but you're going to need herbomistica like you do with most things so that is all you're going to need to do like i say this is going to be able this is going to be a method that you're going to be able to probably do in a bunch of different locations around the region so if you found a different spot where you can do this and pokemon spawn in in this really specific way then this means that you're probably going to be able to apply this method to those locations as well and like i say if i do come across anymore when i'm hunting around the region for these i'll definitely do an update video to say this is another location where you're going to have an easy time getting these shinies thank you so much for tuning in to today's video hopefully you have fun with this little glitch of a method that allows you to exploit a game mechanic where you're going to be able to get the particular shinies from this area a lot quicker you can get slanted from this area as well the tails do spawn from the ceiling so if you want to do slanted here you can spot the white tail poking out from the ceiling and that is a way to hunt this one as well in this particular area so have fun with it let me know if you do try this out how many shinies what your best amount of shinies that you get from this area in one 30 minute sparkling power period thank you so much for tuning in if you found the video helpful please drop a like do subscribe to the channel for more pokemon scarlet and violet content and i will see you all in the next one so until then friends take care of yourselves and bye bye