 going to be about quantum query complexity. I will try to introduce some basics, but also some recent developments as well. There will be a set of five lectures. You can find the materials online in my website. And four problem sessions. So I will give the course mostly using slides, and I will try to do some hosting detail on the board. And if you have any question, during the lecture, don't hesitate to interrupt me. So let me start with a very high level description of what we will try to do in this course, and what is quantum query complexity. So the goal is to prove that quantum algorithms cannot be too fast for solving certain tasks that we may be interested in. So this is called lower bound. And a lower bound is a statement of the following type. You want to show that any quantum algorithm that solves some problem X that you are interested in must run in time at least. So you want to prove some limitation on the power of quantum computers. So this is a different aspect than designing algorithms, but it is also very important to understand the limits of quantum computing. So there are two challenges in following this goal. The first one is to define and to formalize what is a model of computation that we want to consider. There are different ways of formalizing a model of quantum computation. Here we will focus on the quantum query model, which is a very simple model that will allow us to prove lower bound in a quite simple way for many interesting problems. And the second goal, once we have this model, will be to find methods, which are like large family of techniques that can prove lower bounds for a problem that we are interested in. So you should think of a method as being a kind of a recipe that you can use, kind of a general framework that you can use to try to understand what is the complexity of your favorite problem. Okay, so first question is why should we care about proving lower bounds and analyzing the limit of quantum computing? Well, there are at least three important reasons. The first one, as I said, is to understand how far we can go with quantum algorithms, and for which problems is it hopeless to look for quantum speedups. The second important application is in cryptography, where lower bounds in some sense are related to the proof that certain protocols will take a long time to be broken, even by quantum attackers or quantum adversaries. So the study of query complexity can help you understand the security of certain cryptographic schemes. And last, and maybe a bit counter-intuitive reason for which we want to look at query complexity, is because in some lower bounds, is because in some situations, it can give you insights into the design of new quantum algorithm. So it's kind of counter-intuitive because we look at lower bounds with the goal of finding algorithms, which are upper bounds. But you will see, especially in the last lecture, that there are some very beautiful connections between the proof of lower bounds and the proof of upper bounds in this quantum query model. And it turns out that certain important quantum algorithm has been discovered through this connection between lower bounds and upper bounds in this setting. Okay, so let's start with the definition of what is the quantum query model. And then we will see a first lower bound method at the end of the lecture. So this is the model that we will be looking at for the rest of the course. And let's begin with the classical counterpart of this model, which is called the classical query complexity model or decision tree complexity. This is something that has been studied for a very long time. And this is kind of different from the Turing machine view point. And it is defined in the following way. So you have some algorithm that tries to solve some problem and you have some input. Let's say it's a vector of size n, x1 up to xn. And your goal is to compute and to solve some problem on this input. Let's imagine you want to find if the input contains a certain value or you want to sort the input in increasing order. And what's important is how the algorithm can obtain information about this input. And the way it can obtain information is by performing what are called queries. And a query is kind of a question that the algorithm can ask, a certain type of question. And it just received the answer to that question. And the goal of the algorithm is to minimize the total number of question that it has to do in order to solve the problem that we are interested in. What is really important in this query model is that we only focus on the total, on the total number of queries, which means that in between two queries, the algorithm can spend as much time as it wants to perform some local computation. So in some sense, the way we will quantify the running time is through the number of queries which will be done for solving the problem. So here is a simple example. This is for sorting three numbers using what are called comparison queries, which means that the algorithm can only ask what is the smallest element between those two coordinates. So, classically, we can represent the computation by what is called a decision tree. So the way you should understand this computation is you start at the root. Each internal node represents queries. And if the answer to that query is yes, you move to the left. And otherwise, you move to the right in the corresponding binary tree. And when you arrive at a leaf, the leaf is labeled by some output, which is supposed to be the sequence sorted in increasing order. So it's quite simple to see that the height of the tree will correspond to the maximum number of queries that you have to do in order to run this algorithm on any possible input. So the height is really quantifying the query complexity of this particular algorithm. Okay, so just to mention two motivations for studying this kind of approach using queries. The first one is, in many cases, focusing on queries is the right thing to do if you want to capture the difficulty of a problem, meaning what the bottleneck comes from the fact that you have to do many queries to the input. So for instance, for this sorting task, it turns out that you can prove that any classical algorithm that sorts n numbers will have to do n log n comparison queries. So in some sense, the internal computation that the computation in which you don't focus on the queries is not really the true bottleneck, is really the number of queries that you have to do. And the second thing is that those queries give us a grasp on what the algorithm has learned about the input. Okay, if you think of Turing machine, it may be quite complicated to really quantify what has been learned about the input when the head of the Turing machine moves, but it's very simple because we explicitly know what kind of information has been obtained through the queries done by the algorithm. So this is a framework that we will consider in this course. There are many variants of, there are many different setup that you can consider for the problem that you want to solve. I will focus on this particular setup. So for most of the course, we will just try to compute Boolean functions. It means that we have a function f from zero one to the end to zero one. We only consider what are called Boolean evaluation queries, meaning that the type of question that we can ask is, what is the value of the highest bit of the input? And this is what a corresponding decision tree may look like. So at each node, you are asking the value of a particular input bit and at the end of the computation, when you reach a leaf, you want to output the value of f of x. Okay, so those are called total function because they are defined for all possible n bit strings. There are also other kind of functions such as partial function that are only defined over a subset of the Boolean cube. But this setup is already quite interesting and it already captures a lot of problems of interest. Okay, so these are some examples that we will see again and again during the lectures and during the problem session of some problem which can be cast in this framework. So for instance, the or function that ask you to decide if the input is all zero string or if it contains at least one bit equal to one. You have the parity function that ask you to compute the parity of the input bits, the majority function, et cetera. Okay, so as a simple exercise, you may ask what is the classical query complexity of solving those problems? How many query do I need? So for instance, for the parity function, classically, you will have to query all the input bits. So classically, the decision tree complexity will be n. There is no way of gaining any improvement over the trivial algorithm that just queries everything. And the question is, if we introduce some quantum computing power in this model, can we hope to compute those functions more efficiently? So as you may already know for the first function, the or function, we do know of a quantum speedup. This is the so-called Grover's algorithm that can decide this function by doing square root n quantum queries. So we will see in a moment what it means to do quantum queries, but we already have an example of a function for which we will be able to really observe this quantum speedup phenomenon. Okay, so let me give you some mathematical definition of what is the classical and the, but what is really the classical query complexity? So first, the deterministic query complexity, this is some of the weakest model of computation that we will consider. We say that a decision tree computes a function f. If for all input, you correctly reach a leaf labeled by the value f of x. So you really want to be correct for all possible input values. And the deterministic query complexity, denoted by df, is gonna be in some sense the height of the best possible decision tree computing f. So you want to minimize the height over all the trees that correctly return the value of f of x. And a simple observation is that this quantity df is always at most n because you can always query all the input bits and then do some offline computation to recover the output of the function. A second more powerful model, but still classical, is called the randomized query complexity model. So we will have slightly more power over the deterministic model. And the algorithm will have access to randomness. And secondly, it will be allowed to fail with some small error probability. So we kind of relax this deterministic model to try to improve the complexity. So a first way of defining this model is by allowing the use of certain type of nodes that correspond to flipping a bit with probability one half and moving to the right or to the left depending on the outcome of these bits. A second equivalent definition, which is usually more convenient to manipulate is in some sense to fix all the randomness in advance before starting any computation. So what it means is we can fix or choose a family of decision tree indexed by some value r which correspond to the random seed. And on an input x, you sample a random seed and you run the corresponding decision tree dr on the input. Okay, those two models are equivalent. And what's really important is that we have this ability of using randomness to choose a path in the tree. Okay, so again, for more definition, we say that a randomized decision tree computes f. If for all inputs, the leaf is correct, but now with probability only at least two thirds. So we are allowed for a small error probability. And the randomized great complexity is just a minimization over all the trees satisfying those constraints. Okay, and the simple fact is that you always have that the randomized complexity is smaller than the deterministic one. Okay, so this is for the classical definition. Is there any question about them? Yes? It doesn't matter. It can be, you can just output any value that you want. Okay, so I should say that there are many other variants of those models. You will see in the problem session that this one third failure is not that important. We could have chosen it much smaller. There are also many variants of randomized and deterministic. So you could have like one sided error, for instance, meaning you only fail when the output is zero. You could have to have some expected running time, et cetera, et cetera. So there are many variants of those models. I'm just considering two of the simplest possible definition. This is just for having something to compare with the quantum setting that I will define in a moment. Okay, so let's move to what's gonna be the really, what's gonna be the goal of those lectures, which is understanding the limitation of the quantum query model. And let's define this quantum query model, the way it is usually defined. So when I define the randomized model, in some sense, this idea was starting with the deterministic one. Essentially, we can fix all the randomness in advance. And this is how we can define this randomized query complexity. Now you could say maybe there is a way of moving to the quantum query complexity model by in some sense fixing all the quantumness in advance and then running, let's say, a deterministic or randomized decision trees. So this is something which is unclear if we can do such a thing. Instead, we will use a different definition which is based on the quantum circuit formalism. This is completely equivalent to decision tree, but this is much simpler to extend to the quantum setting. So what is a circuit, a quantum circuit? Well, this is something that you have to read from left to right. Initially, you are starting with some initial memory, which is in some fixed quantum state. Let's say this is an old zero quantum state. And what you will do is you will alternate between two types of operation. So the red boxes correspond to applying some unitary operation on your memory. Those unitary do not depend on the particular value of the input that chosen in advance. And the blue boxes will correspond to performing one quantum query to the input. So this is where you can obtain information about the particular input values. So what you do is you apply alternatively those two kind of operation for a certain number of time T. And at the end of the computation, you measure some specified register. Let's say this is a second register. You will observe a particular bit, either zero or one. And this is the output of your algorithm. So the choice of U0, U1, et cetera will depend on what kind of algorithm you want to implement. The choice of OX is fixed because this is like how you get information about the input. And OX is defined as follows. So this is a unitary transformation. This is called the oracle gate. And it is defined as you can see by those equation. So let's say the first register always contain an index I between one and N. And the second register contain a bit B. Then if you apply OX, what happens is the value B is replaced with B plus Xi. Okay, so if B was equal to zero, you would exactly obtain Xi. If B was equal to one before doing the query, you would obtain one plus Xi. So you can check that indeed, this is a unitary transformation. I defined it over a basic state, but you should think of it as being applied over a superposition of many different value I and B. Meaning you can do query on a superposition. So there is one technicality that I would like to briefly mention, which is in the definition I gave, everything was happening on just two registers. One containing the query index. The other one containing this output value B. In practice, you may imagine that an algorithm, a quantum algorithm may require more space than just those two registers. In practice, there are many quantum algorithms for which you need some extra workspace. We can be pretty large. And this extra workspace will only be accessed by those neuteries that you will apply in between quantum queries. This will be used only for this kind of computation that does not depend on the input. So I will not consider those kind of algorithm in this course. I will assume that in some sense, you don't need those extra workspace. So the reason for that is because almost all the lower bound methods that we know in the quantum query model do not depend on the size of the workspace that you have access to. So in some sense, even if you have a very large workspace, we don't really know how to take this into account to kind of adapt the lower bound and take this workspace size into account. This is actually a very important open problem in quantum computation to understand how the size of the workspace has some effect on the query complexity of a problem. Okay, but you can just forget about this point if you want and you can just imagine that there is no workspace for the algorithm that we consider in this course. Okay, so this is how we can formally define the quantum query complexity. So first, we say that a quantum circuit computes a function F. If for all input, the output that you measure at the end of the circuit is correctly equal to F of X with probability at least two-thirds. And now the quantum query complexity of a function F is just the smallest number of rattle gates that you will have to apply if you try to minimize over all circuit computing F. Okay, and a fact is that the quantum query complexity is always smaller than the randomized, which is smaller than the deterministic and which is smaller than N. Okay, so maybe the connection between the quantum and the randomized is less obvious because we kind of use this quantum circuit model. So if I go back just for a moment, you could also define randomized query complexity in this model by asking that those U0, U1, et cetera, there are stochastic matrices. So if instead of being unitary as stochastic, you will exactly recover the randomized query complexity. The fact that there are unitary, this is really what gives you the ability of implementing quantum algorithms in this model. Okay, and the number of blue boxes is what I called this quantum query complexity number. Yes? Yeah, without the workspace, it's not obvious. Yeah, but so this would be an issue if we were studying the design of algorithm in this model, but because we study the proof of lower bound in some sense, this is not really like a problem. So the lower bound that we will show only apply to algorithm that do not have this extra workspace, but as I said, and it's an interesting exercise to prove that all the methods that I will show can very easily be adapted to take into account an arbitrary workspace. Okay, so it is quite an interesting exercise to prove that, and it will always be possible for the method that I show. No, no, no, no, no, no, no, so, I mean, finding methods that are sensitive to the size of the workspace is a research problem. I mean, a method that can give you a separation depending on whether the workspace is big or small, this is what's open, what's mostly open. What is an exercise is to prove that the method that I will show you are not sensitive to the size of the workspace. So in some sense, they fail to do this, I mean, taking this space into account. Any other question? Okay, so we have all the definition that we will need for this course. So now we can move to lower bounds. So there have been since the beginning of the study of this quantum quake complexity model, there has been a lot of attempts to try to design methods that will help us understand this quake complexity, this quantum quake complexity. And it turns out that mostly we know about two big families of lower bound methods. So there are a few exceptions, but most of the method that we know and that we are able to use in practice can be classified into two categories. So on the left, you have the so-called polynomial methods which started with this symmetrization technique and which still actively studied. So the idea of the polynomial methods that we will see in the next lecture is to draw a connection between quantum query algorithm and the study of Boolean analysis. So there are very deep and beautiful connection between the two topics and this connection can help you design lower bounds in a lot of interesting cases. So we will see what is this symmetrization and those dual polynomials technique and more recently there has been new development that uses some more complicated polynomial characterization using completely bounded form, Lorentz polynomials, et cetera. So this is the first family that we will be looking at. The second family of methods is quite different. Those are called usually adversary methods. I would say there are usually much closer to the intuition that we can have about quake complexity classically, this intuition that we have to query many input bits if we want to have enough information about the function. So those methods begin with the hybrid method. This was, I think, the very first method for studying quantum quake complexity. We will see it in a moment. And then there has been a lot of development over this hybrid method in some extension to be more closer to the actual complexity. So there has been those positive, spectral, negative methods that we will be looking at in lecture four and five, a multiplicative method, and also very recently a method which has been developed in the context of cryptography, which is called the recording or the compressed oracle method. And we will have a look at it in the third lecture. So one important aspect of those adversary methods is if you consider the most general adversary method that we know about, and we will look at, we will see it in lecture four, this method is actually optimal. So this adversary method, you will see that it always give you the optimal quantum quake complexity. So it doesn't mean we have solved everything because now if you try to apply it, it may be complicated to apply it to a concrete problem. But in some sense, the way this method is formalized is exactly capturing the quantum quake complexity. So there is no gap between this general adversary method and the quantum quake complexity. So maybe I should ask, who already know about the polynomial method? You can raise your hand. And the adversary method. Okay, and the recording compressed oracle Zandri's method. Okay, so hopefully most of you will learn something from at least one lecture. So yes, during the lecture, but just try to introduce the method and to apply it on a basic problem, let's say the or function. It will be like a good example to see again and again how to apply those methods. And during the problem session, the goal will be to try to apply those methods to more advanced scenarios. Okay, so for today, I will start with a hybrid method. This is maybe the most, the simplest one. So this method has an interesting history. It was discovered in I think in 1998 or something like that. So at that time, people tried to understand what was the complexity of solving this or function? You know, like finding a marked element in a list of values. And before discovering the Grover's algorithm, people actually prove that using this hybrid method that you cannot hope for, let's say an exponential speedup. So the lower bound has been discovered before the upper bound. Okay, so let's try to go step by step to define the method and then to apply it to the or function. So this is again the framework that we are considering in quantum query complexity. So we have this quantum circuit that is making T queries for a certain number T. I recall the definition of the Oracle gate. And for notation, it will be important to consider those intermediate states of the quantum of the memory. So those states psi, x, t, these are the states of the memory before applying the query number T plus one. Okay, so we just have a notation for all the possible intermediate states. Okay, so mathematically, you can define this psi, x, t as being the state that you apply when you start with the all zero quantum state and then you alternate between applying a UI and a quantum query for T times. So of course, this state, it is a superposition over many different value IB because when you apply those unitary UI, you can create a superposition. Imagine for instance that UI is a Hadamard gate. It will create a superposition and then the query will kind of do some computation over this superposition. So there are two intuition that you may have if you try to design a lower bound method in this framework. The first one is that intuitively, if you have two inputs, x and i, for which the output is supposed to be different, so f of x is different from f of y, then in some sense at the end of the computation, at the end of all the t queries, the final states of the memory should be far apart. They should be, let's say, almost orthogonal if you want to have a chance of distinguishing between those two states. So this is the first intuition. The second intuition is that if you want to distinguish between x and y, in some sense at some point, during the computation, you will have to query some indices on which x and y are different. Okay, so classically, this is very, this is completely obvious. Quantumly, this is slightly more complicated to quantify because you can make query in superposition. What does it mean to learn the value of x i? For instance, if I query x i with a very small amplitude, then do I really learn the value of x i? Okay, so this intuition is maybe a bit more complicated to formalize in the quantum sitting, but in some sense we will have to do that. Okay, so let's move to the actual proof. So I will show you the hybrid method in case of the R function. The goal is to compute to decide if an input x is all zero or not. And we want to prove a lower bound on the quantum query complexity of this problem. So in the proof, I will only focus on certain type of inputs which intuitively are the hardest inputs. So there are n plus one of those. You have the all zero input for which the output must be zero. And then you have n inputs denoted by one up to n in which you have a single value which is equal to one. And for each of those inputs, you should output value one. Okay, so those are the hardest input because in some sense, there is just one value that will help you to find the outputs of the problem. And this is the very important definition that we will be used to do the proof. This is called the query weight. It's an important quantity. And it kind of matches this intuition that we have to query certain position if we want to solve the problem. So what is the query weight? This is something that is defined for a particular index i and a particular time t. And this is equal to the probability that if we measure the state of the algorithm after t queries, when the input is all zero states, this is a probability that we observe the index i. Okay, so to phrase it differently, this is a probability that the next query is gonna be on index i when the input is all zero vector. Okay, so those are the definition that we will use. And now the proof will be done in three parts. And this will conclude the lecture once we have done the proof. So the first lemma, so the proof will consist of showing that we have to do many queries if we want to increase some progress measure, if we want some progress to be sufficiently big such that we can solve the problem. So there are three important steps. The first one, the first lemma is to prove that at the beginning of the computation before any query has been done, all states are at distance are equal to each other. Okay, so this is the initial condition. Initially, whatever the input is, the distance between two states, between the all zero state and the state i is equal to zero. The second lemma, this is the final condition or the correctness condition tells you that at the end of the computation, if the algorithm succeeds with probability at least two-third, then the state must be far apart. Let's say at distance at least one-third. Okay, so you have to go from zero to at least one-third. So you have to increase this distance by one-third. The purpose of the last lemma is to show that you cannot increase this distance too fast. So more precisely what we will show is that when you move from query number t to query number t plus one, you can only increase by a quantity which is at most the square root of the query weight where it is indexed by i, if you look at the distance between the state zero and the state i. Okay, and then we will see that if you put everything together, you arrive at the conclusion that the quantum-quake complexity of the or function is at least square root n over three. Okay, so let me do the proof of the three lemmas. We'll do them on the board. And hopefully everyone can see. Okay, so let's start with lemma one. So lemma one is the easiest. We can just look at the definition of those quantum states. Okay, so by definition, what do we have? We have that this psi zero at time zero is equal to psi i at time zero. And those are equal to applying just the first unitary on the all zero input state. Okay, so this is really the definition of the model. Thank you. So can everyone see the board? Yes, okay. Okay, and because those unitary, they do not depend on the input. Okay, they do not depend on x. So those are really like input independence are equal so the distance is equal to zero. Okay, so now second lemma. So for the second lemma, we want to relate the success probability to this final condition on the distance between the state. So first, let's try to formalize what it means to succeed with probability at least two third. So what does it mean? So this is what we could call the success condition. So the success condition, if you remember the definition of the model was, if we measure the output, if we measure the register containing the value B, it must be correct with probability at least two third. So what it means is we will have something like that. So if I look at the projection on this for the state psi zero at the end, okay? So when the input is all zero state, at the end measuring the second register is equivalent to looking at the norm of this projection and it has to be at least two third. And similarly, if the input contains a one, then what we expect to have at the end is this condition. Okay, so how to use those success condition? Well, we'll just compute the distance. So what we want is to lower bomb the distance between psi zero after capital T queries on psi I. Okay, it will be more convenient to look at the square of the distance. Okay, so we can just expand. So this is equal to two times one minus the real part of the inner product between the two states. Okay, so here I use the fact that those psi XT, they are unit vectors. Okay, so what's the next idea? The next idea is to kind of insert inside this inner product two different quantities, like the composition of the identity in the following way. So we can say that this is equal to two times one minus, same thing. But now we only look at the part of the inner product in which we have the value, let's say, the value identity 00. And then the second missing part. Okay, so what I did is just splitting the identity into two different projectors. One is when the second register contains zero, the other one is when it contains one. Okay, so next step. So next step I would say is this is maybe the most important step of the proof and this is something that is used again and again in quantum computing. This is applying the Cauchy-Schwarz inequality. So we can apply Cauchy-Schwarz on each of those two quantities. And what it will tell us is that we can substitute those with some norm. The first one is gonna be the norm when we project on the second register containing zero, for psi zero, multiplied by the same thing but for psi i. Okay, so I applied Cauchy-Schwarz on the first and I do the same for the second thing. So now instead of zero it's gonna be one. Okay, and this is by Cauchy-Schwarz inequality. And essentially this is done because what Cauchy-Schwarz gave us are those norm which are exactly the norm that were used in reformulating the success condition. So we want to understand how small this quantity can be under the condition that those two inequalities hold. Okay, so I'm not gonna do the computation, you can do it, it's a simple math exercise. It's gonna be at least two times one minus two square root two over three. So this is by success condition. Okay, and this is at least one over nine which concludes the proof. Okay, any question? Okay, so let's move to the third lemma. This is maybe the most interesting one which was about showing that, if I move it just one minute, showing that you cannot increase this distance faster than this square root of the query weight. Okay, so lemma three. Okay, so let's start with what we want to upper bound. So we want to upper bound the distance between what we obtain where the input is zero after t plus one query and when the input is vector containing a one at position i. Okay, so here we don't take the squared. We can directly consider just the norm. Okay, so let's go step by step. So first, what we can do, so the goal is to relate that to the same state but at time t. So first idea is to use the definition of those states. So if you look at the definition on the top left, you can move from time t to time t plus one by just applying o x, so oracle gate followed by ut plus one. Okay, so what it means is this is equal to ut plus one. Then you have an oracle gate corresponding to the input zero. Then you have psi zero, but at time t now. And same thing for the other state but now applying the oracle gate corresponding to input i. Okay, this is really by definition of those psi xt. Okay, so our first simplification is, so this norm, this is operator, this is L2 norm. And this is, I mean, applying a unitary over a state does not change the norm of the vector. Okay, so this is equal. We can remove the application of the unitary ut plus one and we can simplify the equation as follows. Okay, so just a comment. So if we go back to this assumption that I made, which was there is no extra workspace register, this is essentially where we can handle extra workspace. So if you had extra workspace on which ut plus one is acting, you can still remove ut plus one, whatever is the size of the extra workspace. So in some sense, this proof does not depend on the size of this workspace. If you want to generalize it to this more general framework. Okay, so let's try to simplify this a little bit more. So first, so what is Rackle gate when the input is all zero state? This is very simple. This is just the identity. Okay, just by definition, if you look at the top right definition, if xi is equal to zero for all i, then you just have the identity. Okay, so I can obtain the following thing. So I will just rearrange the equation. So this is equal to the following thing. Okay, so I just rearrange the equation. On one hand, I have psi zero t minus psi i t. This is good because this is gonna be the term that is appearing on the right. And then I have something that depends on psi zero t. Okay, so next step is to apply the triangle inequality. So we apply triangle inequality to kind of split up this quantity into two terms. The first term is gonna be this o i psi zero t minus psi i t. And the second term is gonna be this identity minus o i. Psi zero t. So this is very good because there are two important observations. The first one is this first term. Again, we look at the norm of a vector on which we applied a unitary transformation. So we can just forget about this unitary. This is equal to the distance between psi zero t and psi i t. Okay, so we got the first term that we needed. The second term, this is more interesting. So what happens if we apply identity minus oracle gate corresponding to input i on this state psi zero t? So my claim is that this is equal to the square root of the query weight. So why is it the case? So identity minus o i, you can write it differently. You can, this is equal to applying a projection on index i and on the second register applying the x gate, the not gate. Okay, and x, let's move to the second board. So you can check the map. Identity minus o i, this is equal to identity times sort of x where x is equal to one zero plus zero one. Okay, in some sense, when you look at the difference, the only term that remain is the term in which, okay, it's not identity, it's i, it's projection on i. Okay, so when you apply this quantity on any state, this is the same as projecting on having the input being, the query index being i and applying the not gate on the second register. Okay, so what does it imply? It implies that now if I applied it on psi zero, okay, what I get is this projection on query index i turns on x, psi zero, okay. X is a unitary, so again, I can remove it from the equation, so this is equal to, this is gonna be the same as projecting on i and applying the identity on the second register. Okay, and this is exactly the definition of the query weight, the square root of the query weight. Any question? Good, so now we can just conclude the proof of the theorem. So the conclusion is any quantum algorithm computing this or function has to do at least square root n over three quantum queries. Okay, so this is very simple. We have everything that we have all the ingredients to conclude the proof. So the first thing is by combining all three lemma together, we have that for all i, if the algorithm is correct, then the sum of query weight from time zero to time t must be at least one third. Okay, so fix an index i, if you are correct, in total, you have to satisfy this inequality. Okay, so now what we do is we just take a summation over all i, so what we will obtain is the following thing, so n over three is gonna be less than a summation over all i, okay, I just take a summation of the first equality over all i, okay. And then we just apply Cauchy-Schwarz inequality again. So by Cauchy-Schwarz inequality, this is gonna be at most n times capital T times summation over both i and t of the query weight. Okay, and last argument is if you fix a value t, if you fix a time step and you take a summation over all i, this is at most one, okay. In one step, the total query weight is equal to one exactly. Okay, so this is equal to t times n, capital T. So this is equal to square root n capital T, okay. So what we showed is that capital T has to be at least square root n over three. Okay, and this concludes the proof. So here you have identity minus oracle gate. So if you apply that to i, let me think, it's maybe identity minus x, it still works, but it's maybe identity minus x, okay. Any other questions? Okay, so during the problem session, we will see some kind of generalization to order function, kind of a large family of Boolean function to which we can adapt this technique. And also some standard trick that we used in quantum query complexity, some basic technique. And then, so in next lecture, we will move to this polynomial method, which is using a kind of very different ideas, okay. Thank you.