 So, our first speaker is R. Venkatesh, he's the chief scientist and head of the Foundations of Computing Science Research at TCS Innovation Research Labs. So, he works extensively on applications of formal methods in several industrial problems and he's going to talk about some of those today. He's also currently the chair of the ACM India Education Committee, the vice president of the Indian Association for Research and Computing Science under whose age this FST-TCS is being held and he's also a member of the ACM Worldwide Education Committee. He leads a very strong team of formal methods at TCS and their team has won several awards including at the Software Verification Competition Award in recent years. So with that I'll hand it over to Venky. Good morning everybody and thanks to Supratik for the introduction, thanks to the organizers for having me here and apologies to everyone for spoiling your study. So this talk I'm going to present more on applications of SAT SMT to industry scale problem. So firstly let me acknowledge almost nothing is my work so it's all these are the guys who have done it I'm just get the privilege of presenting all that to you. So here is a long list of people who have done it I may have missed some names here but it's not mine. So the main point I want to make in this talk is that SAT SMT has a wide range of applications in the industry and we have been using it in a lot of many ways and very successfully to solve actual industry problems which are being useful. I will present two of them here, one is for proving properties of programs which is an interesting application of SAT SMT and also one optimization which was that's very different I think one wouldn't imagine using SAT SMT for applying for optimization problem and I'll present what we have done out there. There are many other places we have done but due to lack of time I won't be getting into details of that. Another point I want to make is yeah there is SAT SMT at the bottom but you need to do a lot of massaging to the problem encoding before you can really exploit it and take advantage of SAT SMT to use. But SAT SMT, so whenever customers come to TCS nowadays I tell them, one of the things I tell them is SAT SMT is underutilized in the industry. It's got much far greater potential than what it is used for and it's underutilized and they are started listening to us and they come to us more and more with more and more problems say can you do this using SAT SMT, can you do this using SAT. So it's gaining acceptance in the industry. So the main theme, naive encoding just doesn't work even for the smallest of industry problems. It just doesn't scale for the smallest of, so you have to put in a lot of effort into getting the encoding right so that it scales up. And for that you need to exploit domain properties. It's not something that can be completely, of course whether it can be automated is an interesting question by itself, but one needs to know the domain and exploit properties there to be able to scale SAT SMT to industry. So the first part of the talk I'll be talking about using SAT SMT for verifying programs which itself is an interesting application as you will see. There we are exploiting two properties, one is, first one I'll talk about is invariant templates. How do you guess invariants and I'll motivate the need for guessing invariants to do that. And second is a small model property. I won't talk too much about the small model property because I don't think I'll have time. I'll get into a lot of details about one particular technique we use for invariant template that is searching through a syntax base. I'll talk about that in a great detail. And in the optimization I'll say how to exploit equivalences. So there are multiple things which are equivalent. If you can somehow encode that into the sort problem, the search space narrows dramatically and therefore it has zero and extending partial solutions. How do you split a problem into small components, solve one problem and then try to extend it to the next part of the problem. So those are the two main points what to make in the second part of the talk on constraint optimization. So the verification problem is you're given a piece of code, we'll assume C for now and you have given an assert and you want to check whether the assert holds or not. This is the classical verification problem and the challenge here is programs have loops of unknown bound and SATSMP cannot handle loops in general. So you need to somehow get rid of loops. So what we do is try to prove properties here. SATSMP is very good, has been used successfully to find bugs in these because there you can unroll loops for a finite bounce and then if there is a bug in that finer bound you have a bug. But when you want to prove it, you need to somehow abstract it out and try and eliminate the loops. So we try to eliminate loops and you'll see one technique that we have, one technique I'll present on how to eliminate loops but there are several other techniques. And for all our applications of verification problem we use CBMC which is a C-bounded model checker which takes a C program and converts it into a SAT formula before it gives it to a SAT solver. So the reason we use CBMC is it does a lot of floating point encoding, integer encoding and all that it does. So we don't have to worry about all that. And so that's the problem that we'll address. So in this talk is going to be about invariates and how to discover invariates. And so it's a brief introduction to invariates. Most of you should be knowing what it is but those are not. It's a property that holds invariate at the program point if you're given. It's a property that holds at that program point for every run of that program at all times. So whenever code reaches that particular point it holds. That's an invariate. And what is interesting is what is called as a loop invariate. It's something that holds when you reach the head of the loop, that is when you reach the loop and it holds within the loop at every iteration because it's nothing. And an interesting property of loop invariate is the final one. So finally when you have i and not b, it holds at the end also at once a loop is terminated, the loop invariate still holds and the not condition of the loop condition holds. So that's a loop invariate and this is something that we'll be exploiting in the technique that I'm going to present right now. So as I said loops in general are difficult to solve using SAT solvers because you need to unroll them and SAT you can unroll them only a finite number of iterations and you still want to prove a property. So when you want to prove a property you want to say it holds for all runs. So you can't really do it for a limited number of runs. CBMC is a bounded model checker. What that means is given any loop it unrolls it for a finite number of times and it checks, converts that to a SAT formula and checks only for that property. So the property may hold for all runs or it may not hold. But if there's a bug it usually the bug is there. So it's a very effective tool for finding bugs but to prove properties you need to somehow abstract the program. So what do we mean by abstraction? Abstraction of a program is another program which allows more runs than the original program. So because it runs it allows more runs if a property holds in the abstract program it also holds in the original program because the abstract program allows more runs. It allows all the runs of the original program plus more plus some more. So these are two things that we will do and so invariant is a way, invariant is an abstraction. So if you run a program only for states that for which the invariant holds then it's an abstraction. So it allows more runs it may allow more runs than the original program. So invariant is a way of abstracting program and it allows helps us eliminate loops by abstracting it. So here is an example. So you have a simple loop here x is equal to y equal to 0 it's initialized while star star means it's a non-deterministic choice. So at any whenever it hits that while star it may enter the loop or it may not enter the loop but you don't know what that condition is. And then you have x is equal to x plus 1 and y equal to y plus x at the end you have to assert that y is greater than equal to 0. Here we are assuming there are no overflows for now because overflows add a entirely different dimension to the problem. So for now we assume that there are no overflows and we assume that it's been checked that there are no overflows let's see. So we want to assert that y is greater than 0 greater than equal to 0. So here we have potential invariant. Assert that x is greater than or equal to 0 and the assume here says that at this point you assume that that x greater than equal to 0 holds. So you are only going to consider runs where x is greater than or equal to 0. You are not going to consider any other runs where you say assume x is greater than equal to 0 you are saying that consider only those runs where at this point x is greater than or equal to 0. Because you just abort and then here this is the invariant at the end of that loop body assert that x is greater than or equal to 0 and because you are not changing it it goes up and then you want to assert that y is greater than or equal to 0. So what we have done here is we have got rid of the loop. Because we have introduced invariance we have got rid of the loop and therefore if this if the property holds for this program it will also hold for the original mark. Yeah, proof of whole there is it. The only difference is we are proving it using whole logic for all kinds of programs is hard because you need to come up with the logic logical argument why this holds for each individual program separately. Whereas when you use a SAT SMT solver it is just a single you really do not care what the body is in the SAT SMT explores all the entire state space to get the that is the basic difference. So depending on the program you have to come up with the argument a proof of why that is an invariant whereas when you are using a SAT MCT it just explores the entire state space by brute force and using brute force and therefore it is a more uniform. So it is more automatable whereas whole logic is not that automatable that is the primary difference. So the question is how do we discover these invariants that is so one way to discover these yeah because so invariant has to hold when you at the initialization point. So you are checking that it is to check that it is indeed an invariant even there I have fudged a bit so that it fits quietly in the but that assert is correct. So you have to show that the invariant holds when you reach the loop the initial at the beginning of the loop at the beginning of the loop that is what that assert checks for. Then we are forcing the X should be more. Then you are making an assumption that it holds for an arbitrary number of iterations so you are proving inductively and you are checking that it holds at the initialization point. There needs to be some more things that are done to get it absolutely correct but just for compactness I have presented it this way. So we are going to look at one particular technique to discover these invariants and so what we are going to do is search in a carefully constructed syntax space. So we define a syntax space search in that syntax space for various expressions and check whether that expression is an invariant or not and we will check whether that expression is a safe invariant or not. So what do we mean by safe invariant is it is an invariant and it is also proves that the property holds the property that we are trying to do. So in this case X greater than equal to 0 is an invariant but it is not a safe invariant. So it is inductive but it is not sufficient to prove that y is greater than equal to 0 because y can take any arbitrary negative value. So we want to search through a grammar, define grammar and see and this technique is used fairly now it is used quite a bit in program synthesis and even before it was used by Dicon to find likely invariants. So Dicon is a dynamic tool which has templates, it looks at runs and sees which of those templates holds. And now Sumit Gulbani's team in MSR, Joshua Tananbaum's team at MIT are using this technique for program synthesis where they define a syntax and explore that syntax piece for all programs and check if any of those program is a valid program, it is a program for which is examples are. So it is a similar idea. So program synthesis and that is why we are calling it invariant synthesis where you search through a syntax piece to check for all through all expressions to see and see whether that is an inductive invariant and is it a safe invariant. These two properties will be real. The key challenge here is that that search space is really large. The program syntax, the syntax page of expressions is really large. So the main problem is on how do you restrict the search space. The main challenge is how do you restrict that search space so that you hit a good invariant soon. That is the key challenge, be it for program synthesis or for invariant synthesis. One common technique that is used is to assign probabilities to syntactic constructs so that you search, you pick more likely expressions more often and less likely expressions less frequently. That is the standard technique that is adopted and so that you hit a good invariant very quickly. So that is the crux of the problem, how do you organize that? And we can also get some assistance from data that is if you run the program, you can get some assistance. Daikon does that which is runs the program and you can, it is easier to analyze data for invariants rather than the program itself. So that is what we will be. So what we are going to look at is can we restrict the size of the grammar by looking at the program itself. So pick up syntactic constructs that are present in the current program and search through only those constructs to look for invariants. That is the main thrust of this problem. So consider this example, the same example again, x equal to y equal to 0, x equal to x plus 1 and y equal to y plus x in a non deterministic loop and you want to assert that y is greater than or equal to 0. The safe inductive invariants for this are x greater than equal to 0 and y greater than equal to 0. x greater than equal to 0 is inductive, but it is not safe, y greater than equal to 0 is safe, but it is not inductive. So the safe and inductive invariant is x greater than equal to 0 and y greater than equal to 0 or x greater than equal to 0 and y minus x greater than or equal to 0. So, the question is how do we search through the, what is the syntax space that we search through to discover these expressions quickly and be able to in a scalable manner. So, again this is just an example where what we are do what we do is look at the constructs there in the program and derive extract expressions from whatever we have seen at the in the program. So, from x is equal to 0 the initial x is equal to 0 you get x greater than equal to 0 and minus x greater than or equal to 0. So, we do not use equal. So, x equal to 0 you get x greater than equal to 0 and similarly for y you get minus x y greater than equal to 0 and then you have x plus y as an expression and because greater than equal to 0 is there we get x plus y greater than equal to 0 similarly y greater than 0. So, these are expressions that we get we extract these expressions from the program we assign probabilities to it we will see the next slide gives more details on how we get the expressions and the probabilities for this program. So, I did discover identified these expressions from the program code we search through all expressions and check is it a inductive invariant safe inductive invariant or not and when we hit a safe inductive invariant we stop or we time out these are the two things that we do. So, we really do not find bugs we only check for whether it is a correct program or not. So, we will see in the next slide. So, here is how we get the sampling grammar. So, you have a the constants we take whatever constants are there indices we take 0 is always there and 1 and minus 1 come from that x greater than x and these x greater than equal because x equal to 0 you get 1 and minus 1. The variables are of course, x and y these are the only two variables that are there in the program and linear combination of variables k dot v plus k dot right and then you have the candidate which are disjunctive expressions inequality and the probabilities itself is determined by frequency of occurrences of. So, for each of these constructs for k equal to 0 1 and minus 1 we assign probabilities to 0 1 and minus 1 depending on how frequently they occur in the program as a similarly for greater than equal to and greater than we assign probabilities based on how frequently they occur in that piece of code and that is how. So, once we have assigned probabilities and we have built this grammar constructed this grammar we explore this the space different the language space defined by this grammar selecting expressions based on probability using the probability distribution that is defined right. Having selected an expression we check if it is a safe invariant if it is not a safe invariant we abandon it if it is an inductive invariant we retain it even if it is not safe because it could be conjuncted with another invariant later occurrence in the program yeah. So, that is just one part of it then we conjunct that like I said conjunct that have already been proven to be inductive we retain and that can be conjuncted with any other expression that we discovered to be seen to check whether it is a. So, for example in the in the example that we saw x greater than equal to 0 is inductive, but it is not safe. So, if we hit x greater than equal to 0 we should we discover that it is inductive. So, we retain it even if it is not safe and then if we sample y greater than 0 equal to 0 then we can conjunct it with x greater than equal to 0 to check is it inductive yeah. So, that is how we and we use some very simple this thing to eliminate. So, if you have already sampled x greater than 5 we do not sample x greater than 4 that is all, but these are very simple rules that are encoded to check. We do not use SAT SMT to check for such and then finally we also use runs of the program to check whether there are likely invariants or not. So, we run the program and then we in the run we have this bunch of templates and check if any of those templates hold for those runs and pick that with the high probability as a invariant to be checked and there is also work that is been done on getting interpolants from bounded proof. So, basically you get a expression you know that it is not a safe invariant you get a trace that is generated and use that to derive an interpolate to get the next potential invariant that is the interpolant run. So, these are additional things that we use to restrict the space not restrict actually order our search through the expression space. So, that we are likely to hit an invariant faster than what I will say. So, now how do we handle multiple loops? So, here again for the first loop the invariant is x plus y plus n equal to m the second loop it is x plus y plus n equal to m and n equal to 0 and the third loop it is x plus y plus n equal to m and n equal to 0 and x is equal to 0 to be able to show that m is equal to 0 at the end. So, we need to discover 3 sets of loop invariance which together are safe. So, you need 3 loop invariance which together are safe that is the problem here and so, basically both arbitrarily x and y are incremented. So, x plus y is plus n is and m is equal to n. So, the this works because m is equal to n out here and you are incrementing x and y while decrementing n to 0. So, x plus y will always be m at the end of this and n becomes 0 right and here again you are decrementing m till x becomes 0. So, now y will be equal to m and then you are decrementing y till m becomes y becomes 0 therefore m becomes 0 right. So, when there are multiple loops again for a large program if you take the syntactic constructs from expressions from the entire program the search space still becomes pretty large. So, we restrict ourselves to each individual part of the program to extract syntactic constructs. So, for the first program we take all these x equal to 0, y equal to 0, m equal to star, n equal to star basically m equal to n is something that can be discovered there plus variables used in these loop in this loop. Those are the expressions that we use to define the syntax space for the first part of the program to discover an invariant right. Then for the so, that gives us this set of expressions and from that you get the grammar that follows. This grammar is very similar to what we saw earlier. So, that is the grammar that we this is the space that that we search for. So, we have this space we have probabilities and then we search through this space to check is there an invariant. It comes again x equal to 0, y equal to 0. So, x greater than equal to 0, x minus x greater than equal to 0. So, if you have x equal to 0, you get x greater than equal to 0 and minus x greater than equal to 0. So, you get minus 1 coefficients. There k is all coefficients of whatever coefficients have been used in the variables. So, k should be 0 also. So, this defines a syntax space and we search through this systematically given probabilities using probabilities we search through this systematically till we find an invariant. Then for the next part of the program that is you for this you have those expressions and from that induces this grammar. So, the second loop has those expressions and that induces this particular grammar. Remember notice that n comes here from the first loop all we get is the negation of the condition n not equal to 0 makes it n equal to 0 at the end of the loop and that is the condition that we get and we that induces this particular grammar. And then for the third loop again x not equal to 0 gives x is equal to 0 and it induces this particular grammar. But note one thing that in all these grammars we will see the next slide the invariant we wanted was x plus y plus n equal to m and none of these grammars really produce a three element expression they all produce at most a two element expression. So, here you have a two element we will see in the next slide anyway. So, you have a two element expression your kv plus kv whereas what you need is a three element expression which is not there in the code. So, you need x plus y plus n whereas at most you can get x plus y you cannot get x plus y plus n using this grammar. So, this is an invariant that cannot be that is not part of the language defined by this grammar. The invariant is not part of the language that is defined by this grammar. So, that is where we use data. So, one simple ways of course we can say these expressions can be arbitrary long, but then it would not scale up because then it the language that is defined becomes much larger. We can one way to correct rectifies is just enhance the grammar, enrich the grammar to define a much richer language, but then the language the sentences in the grammar becomes too many and searching through that space does not scale up. So, instead what scales up really well is dynamic analysis. So, you have runs of the program there you can search for a much richer set of templates especially all linear templates you can search for and from those traces what you get are likely invariants. You get some properties that from that are true in the traces. Now those are additional expressions that you can consider for your safe invariants whether check whether they are invariants or not. So, they are likely invariants their traces do not tell you that they are invariants, but they give you expressions that are likely invariants. They eliminate traces eliminate a lot of expressions and they read. So, they only identify some potential ones. So, you can use those and then check whether those are invariants in your program again apply the same techniques that you do to check whether it is an invariant or not. And you can once you have an invariant at the first then you discover x plus y plus n equal to m for the first loop quite easily. Now that can be propagated also because there is no none of them are modified between the two loops because there is no expression between the two loops. Therefore, it falls through to the head of the second loop and therefore, it becomes a potential invariant for the second loop. And you can show that it is indeed an invariant again it falls through to the third loop because there is nothing no expression between the two. And so, those invariants can be propagated and you search your search space now becomes richer slightly richer and then you search through that to get the invariant. So, to check whether it really heads we tried this on several benchmarks and compared it against Frequon is the one even tool on which this has been implemented and here are some numbers. So, it does indeed help scale up a bit. So, this is all a 5 minute timeout to discover invariants on these programs. So, what is interesting is it also helps discover non-linear basically disjunctive invariants too. And the probability assignment also helps. So, when you run it without probabilities it solves only 65 errors with probabilities it solves 81, where probabilities were derived purely using frequencies, occurrences number of times a property occurred in the program. No, we do not look at the data to derive probabilities. The data we use only to come up with likely invariants. So, the program synthesis community looks at program sets to arrive at probabilities. That is a possibility. Like I said told him the programming a program synthesis community does that. They look at all possible programs to arrive at probabilities of expressions. We have not done that, but I do believe that that is a useful way forward. But then I think it is would not be that straightforward. So, what they do is to get all the program they randomly generate programs which may not be representative of practical programs. And so, it is getting that data is not that straightforward. And they work on lists. So, generating randomly generating programs is much easier. So, now we look at extending the same ideas to arrays programs with arrays. So, till now we saw examples of programs without arrays. And the obvious question is how do you expand extended to programs with arrays? Because you obviously need to introduce a quantifier for all in this case, but it can be anything actually for all of that. And what is the search space? So, you want to extend it to arrays without impacting the search space too much. You do not want to enlarge the search space by too much. You still want to be scalable while you are still doing. So, we just do not want to add a for all arbitrarily to the grammar. Because then it tries for all kinds of quantified variables and that explores the search space. So, how do we restrict that search space? So, that we are able to search through it. And so, here is one program. So, the first loop just finds the minimum m in the array, second loop just subtracts and third loop just sums up b i's. And then you just want to say that this thing is greater. So, here we assume a i's are all non-zero, greater than 0 sorry. So, m is the minimum element smallest element in the array. The second loop just subtracts from m from a i and assigns to an element in b. And the point is that all elements in b are greater than 0 because m is the smallest element. That is the key point here. We assume and then you just want to assert that s is greater than or equal to 0. So, how do we get these quantified expressions? So, we just introduce an arbitrary variable j and look for quantified expressions in the loops the loop head which is in this case for i equal to n minus 1 i greater than equal to 0 i equal to i minus 1. So, we have j i less than j and which is less than equal to n minus 1. We get that expression from the first loop. And from the second loop, we do get this from the first loop and we additionally get this right hand side expression. This expression we get from again from the first loop and this expression we get from the second loop because it is there in the second loop. So, there are there is a quantified part of the expression and there is a right hand side part of the expression. The right hand side part of the expression we do exactly what we did earlier, but there are some array expressions now. That is about it. Because your a i is being used which is the loop variable we just use here replace that i with j and say for all for j equal to. So, we take the expressions that are there in the loop body replace the loop index with the newly introduced variable j and we get a gradient expression. And for the third loop we get that additional the s greater than 0 of course, we get from the last. So, the right hand side of the expression is exactly like what we did earlier except when there is an array expression. It is the if there is a loop index inside the array expression that you replace by the quantified variable. But otherwise it is exactly like what was done in the for the rest of the. So, this just explains what we do. So, introduce a quantified expression, introduce a single quantified variable j for all the loops because there the scope is anyhow local to that loop. And the expressions for the quantified variables are based on the counter variables here. You get the expressions based on the loop heads if it is a for loop you get it we assume it is all for loop and we get it from the loop heads. And the cell formula itself is grammar constructed from syntax as we had done earlier. So, what we are really doing is trying to restrict the search piece remember that strategy remains the same define a grammar through which you can search for and then use the same loop propagation induction the invariant propagation techniques where that we used there earlier. So, here this just comes to the next one right and this is the invariant you discover for this that is of course there in the loop body. So, there is nothing yeah. So, now if you are given a i is greater than 0 you automatically get s s greater than 0 at the end of. So, this is something that we use to get expressions the grammar and the expression space through which we can search for invariants. Having done that it still does not always necessarily scale it does not necessarily scale to. So, wherever possible we try to eliminate yeah. You are using SAT SMT to do the sampling? No no SAT SMT we finally we use all this we do not use SAT SMT till and then once we have transformed the program with the invariants we use SAT SMT to check is it a safe invariant. I see. So, the sampling is done. Sampling we are not doing using SAT SMT sampling. So, we just so there is no sampling really. You have to sample. So, given probabilities yeah we do not we have to sample through a grammar. Yeah. Yeah. So, that we are not using. So, for that we will have to encode the grammar and we have not even given it a thought to be honest. Some kind of important something. Yeah correct it is a possibility, but we have not really given it a thought. So, there is there are other applications to where we could use SAT SMT for sampling, but we have not yet tried that. So, in some cases you can eliminate the quantifier. We will not get into details, but you can eliminate especially when you know that the loop body only one or two indices are used then you can where tiling kind of ideas can be used borrow to eliminate quantifier. So, here for example, you have for instead of saying for all j you can just say that the next iteration it is doing that because the rest of it is not getting modified. So, tiling ideas can be used here and we also generalize sub ranges. So, and here are the experimental results that we have had for this particular idea. So, Booster used to be a fairly good array tool. VIP is a pretty good array tool and they have the best array scores in SV Comp last year. So, it does indeed help and more importantly I believe that this is a fairly general idea that can be expended for programs that have invariance because not all array programs are may have may be provable using an inductive in not all loop programs may be provable using inductive invariance, but if programs can be used using inductive invariance I believe this is a fairly good framework to use. We need to of course generalize make the search space thing more powerful than what has been done which is right now we are just sampling from grammar maybe we can think of extending it a bit more. So, the way we might go is run the program, get generate some data, discover some likely invariance, analyze the program. So, for example, here we are looking at only syntactic there is a whole static analysis gives a rich set of relationship between variables. Use that information to define the expressions that needs to be searched because static analysis will be able to tell you what variables are likely to be the invariant much better than just looking at the syntax. And so this whole approach I think is very promising when you want to solve a large or use one a very generic technique to prove a large property of set of programs. Otherwise what happens is you have some technique to solve address a specific class of programs another technique to solve another specific class of program this I believe will work should be able we should be able to extend this to work for programs that have induct that do have safe inductive invariance. So, in summary we have a guess and check framework for invariant synthesis and we will continue to expand on this. This guess and check framework allows us to reduce a program with loops to a program without loop so that we can use a SAT SMT solver to check whether the property holds or not. And this of course right now we are using it only to prove correctness we are not really using it to we cannot use it to find bugs to find bugs we will have to extend this further. And this general yeah. I might have missed this, but in this guess and check framework if a particular candidate invariant does not work do you get any feedback that you then use to guide the search to the grammar? Do we get a feedback we use I know right now except in the mechanism where we the interpolant that we do. So, if there is a it does not if it is not an inductive invariant or it does not if we generate the SAT SMT generates a trace we use that trace to get an in can be used to get an interpolate to find the next that is the only place where we use it. Ganesh maybe I missed something here yeah I get the flavor of the approach. The point is you know there are there are tons of spurious invariants which are true I mean for example true you know it will always be true it will be inductive. True true true. So, surely you are doing something more interesting. So, do you rule out you know the ones which are not useful I mean see this is the critical thing right. Yes. Do you for example infer the strongest invariant like Dijkstra did or. No no so we do not infer the strongest we infer safe invariants. No no but our true is a safe invariant you do not mean the same method. It is not true is not a safe invariant. Okay it is too large yeah. Yeah. But what I am saying so we are search stops when we hit a safe invariant. Okay false. Huh? False is a safe invariant. False is false. If you start with false after the iteration but it has to be true. Yeah yeah of course. Okay so you have a forward flow for consistency. So we do not discover the strongest invariant we discover safe invariant. Yeah. As soon as we hit a safe invariant we stop. Okay my examples are bad but there would be many many invariants. So yeah you are right. You are right. So firstly our syntax search restricts our search quite a bit and secondly if we discover an inductive invariant which is not safe we may consider it next time or we may not consider it the next time. Yeah. So it we do not always include it. So to again restrict the size of invariant to eliminate spoorius invariants. But at the same time we do not totally eliminate it because it could be useful. Absolutely. So when you said that the one example that you had where you had x plus y plus n plus n and you did grammar did not generate it because it was scared up it is exactly for this guessing part it won't scale up checking wouldn't have been a problem. Guessing is the scale up scale up is largely the guessing yeah the guess the number of the search space. Okay. Yeah it's a search space that we want to restrict because it's guess and check that entire search that entire iteration that we want to limit. Yeah. So that is just one of the ideas that we have implemented in this tool very apps but what is common to all of them is this program abstraction which takes a arbitrary C program and converts it into a program that does not have loops that when I say that does not have loops it means that either it does not have loops at all or it has small finite loops with small known number of iterations which is equivalent to not having loops because you can just unroll those loops and eliminate them and these are the techniques that we have been implemented in that one is array shrinking or pruning which is something we did with Sanyal here and Shravan loop acceleration which we have been doing for several years k induction is another thing and loop invariant generation which is what we so I think the other three have already been presented in some SAT SMT school or the other so we chose the loop invariant one for this one. So and then now you have an overapproximated program which doesn't have a loop it doesn't have loops or loops with small finite bound that you can use a sat a bounded model checker or SAT SMT formula to that you can translate to an SAT SMT formula and then use a solver to check it that's the general framework that we use and it has done quite well as far as the SV comp competition is concerned we mainly participate in reach safety because it's ours is all about proving properties we are not they don't participate in their concurrency or any of those and these are the numbers from last year this year too we have entered but results are are not yet out and so it does help these SAT SMT is fairly useful in being able to scale up and the competition includes SEGAR kind a lot of SEGAR tools and I think CPA checker the second is a SEGAR based tool interpolant use a tool using interpolates and then there are bounded model checking tools which they have lose all kinds of techniques to scale it up so ours is the only one that really translates it into a SAT SMT formula and then checks for whether it's holds or not and we have applied this even for industry programs where we use it to so we have a static analysis tool which generates a whole heap of false positives and we use this technique to eliminate the false positives automatically and it has been fairly successful in very large programs 400,000 lines million lines kind of code we have applied the similar technique to eliminate false positives it doesn't solve all of them but it eliminates quite a lot of false positives automatically there is still a lot of room for improving scalability and improving the checking for that brings me to the second part of my talk which is harness constraint optimization so this is a problem that where customer came to us and this is an automotive customer they came to us and said all automotive vehicles have they have to schedule before a vehicle goes into production any model goes into production they need to test it thoroughly test for all features and test under all kind of conditions and because the this thing is so what we are doing is there are a lot of constraints when they do these tests so a feature has to be tested automotive manufacturer may produce several models of a car and these features have to be tested on each of the models there are constraints which says that certain tests have to be performed before certain other tests there are certain constraints that a certain test has to be the last crash test being an obvious example it is the last test it has to be the last test on a car there are constraints on schedules which says that all tests because they want to ship out the model so they have all tests have to be performed before a certain date that is another constraint that they have and tests on one model are independent of the other so if there are manufacturer models to models of cars they are independent except test the testing facility capacity they use the same testing facility and that capacity is limited so those limits are also known manufacturing capacity is limited because when they are manufacturing these test vehicles they can only manufacture one or two vehicles but they they they are not in a production floor yet so they can only manufacture one or two vehicles in a day and the objective is to minimize the number of test vehicles so if they reduce the car by one they save a million dollars yeah the number of test cars if they reduce by one they save a million dollars because the of the whole because manufacturing one vehicle is pretty expensive so that is the problem and it is not initially obvious there are integer linear programming there are a lot of optimization solutions for optimization problems and so it is not immediately obvious that one would apply SAT SMT to solve an optimization problem so but this came to us again just because I had been telling everyone that SAT SMT is being underused and so they said okay prove it to us so here are some constraints priority constraint so if a car has a priority over another it should be tested if a test has a priority one test has a priority over another then if it's being two tests are being performed on the same vehicle the higher priority test should be performed before the lower priority test that's the priority test obviously cannot overlap you cannot perform two tests simultaneously on a car last to be done first to be done on a car which they call as position for some reason uh end dates there are some tests which have to be done on the same vehicle and there are constraints on the infrastructure assembly order so for again this is an arbitrary constraint the car that gets manufactured they want to perform more tests on those cars it's a it's a requirement that they have for some reason I don't know why but they have that requirement a testing facilities of course are available and then there are geographical constraints so cold tests have to be performed in colder regions hot tests have to be performed in hotter regions so you need to ship cars from one place to the other the constraints are many and the problem is to minimize the number of car given the number of uh days and some of these constraints are soft they said they don't mind them being violated but you have to violate as few of them as possible so you have to minimize the number of cars and violate as few of these some of these soft constraints uh as possible so what we have done is modeled is as a SAT problem and use Z3 as a solver SAT SMT problem and uh one advantage of modeling it as a SAT SMT is modeling is easy because all these constraints naturally fit into a logical framework a SAT SMT kind of framework you don't have to encode it as an integer problem whereas if you are using an ILP solver you have to encode all of this as an integer problem and uh try so we felt that this is more intuitive if it works well and that's the reason we modeled it as a SAT SMT problem so a knife encoding into SAT SMT would be as follows these are some examples so you define car as a function and uh whether a test car is a function on which a test is being performed so if car i equal to j then uh test i is done on car j that's what it means similarly start date is a function end date is a function where you have start dates and end dates that uh defined as this is a straightforward position remember position is a test that has to be performed first on a car that is no other test should follow a test that is a position so this just says for amongst all tests if that test is being performed on that car it should be performed after the position test so that's the first one second one is priority which essentially says if two tests are performed on the same car then the higher priority test should be performed first so if i has a priority greater than j i has a priority less than j then then yeah so i said it the other way then end of i should end before j starts overlap is test shouldn't overlap that's an obvious uh constraint and we started off with this knife encoding which which doesn't scale because there are about thousand tests that need to be performed but which leads to around 1.1 million variables and around 10 million constraints so when this whole thing was encoded this is the uh numbers we got so even scheduling tests is a pretty challenging problem and this is something they were doing manually using excel sheets and uh using a whole lot of domain knowledge so one of the first steps we did was we split it model wise we said we will model each problem the test problem for each model of car a separate problem so that it gets split into multiple uh problems this is not always optimal so what we do is we run it for the one model derive so for instance test facility capacities those those will change so certain tests are performed at a certain facility between on a certain date let's say now that capacity is utilized for that date so that we add as an additional constraint when we are performing the next model right so we solve for one model derive at additional constraints when we are solving for the next model so that no constraints are violated so none of the constraints will be violated when we are doing it model wise but what will happen is you may not get an optimal solution so you may get a sub-optimal solution that's the limitation and right now we don't have a workaround for that so we say we will live with the sub-optimal solution for right then they were apart from just splitting it across models there were other changes that we had to make because even splitting it on across models didn't really help was not sufficient so there are certain constraints the dates in particular start date end date and that whole there's a start date and an end date combination which acts a lot to the complexity uh on this thing so instead of using the start date end date as a complexity we introduced something called an order so you just say order just define the order in which tests are carried out on a car order is a function that non-deterministically determines that order in which tests are carried out in a car so if uh then you have an order constraint which just says if order i is less if i is less than j and they are both performed on the same car then the test i should end before test j starts so you eliminate a lot of these start date end date constraints that are there so now all these becomes become much simpler using order instead of start date end date position in particular becomes really simple as a encoding so you just have that order of whatever is the position test is position test has to be have an order one on whichever car it is it should always have an order one then priority also instead of combining start and end now it just compares orders and uh that's what priority does similarly for overlap you overlap you just say order they are ordered so the two no two tests are the same order so another requirement that they have is the tests have weights they give weights to tests and cars that perform so if you accumulate weights of a test on a car a car that has performs more weighted tests have to be manufactured before cars that have performed that have that carry out fewer tests in some sense if you assume weights are same equal one then it's translated to that but tests do have weights so it's weighted sum of tests carried out on a car whichever car has higher has to be manufactured before other cars and so we had earlier encoded it as an if then else if weight is greater than then manufacturing of that car should be before or at the same time as a manufacturing of a lower car and then instead later on what we did was just fix again non-deterministically fix the order in which cars are manufactured so car one is manufactured first car one car two this notice is a domain knowledge because you're saying two cars are equivalent two cars of the same model are equivalent and you really don't care you don't want to really try all orders of cars this is just exploiting equivalence of cars when there are tests so you fix the manufacturing order of cars and then say the weights have to be higher so it gets rid of the if then else which if then else is a fairly expensive operator when it comes to uh satisivity so here are some numbers so when we did the model-wise split if there are eight and six cars we are talking of there so these are very small the number of tests is 52 we just had 52 tests so we had some examples with just 52 tests if number of cars are Z3 times out after we merge constraints it does it in four minutes and 72 minutes timeout is 480 minutes so as you can see very simple changes in encoding which may things that may seem obvious bring out a dramatic change in the scalability of a test so they're eliminating the if then else for manufacturing order where we're just exploiting equivalence of cars reduced it from 4 and 72 to 2.5 and 5.5 but that's for 52 tests remember we need to do for 1000 tests the problem is to do it for solve it for 1000 tests this is for the next three models choice elimination is the this one where the cars are seen of course here i'm showing one example there are various places it applies there are remember there are 10 million constraints and also the number of constraints is oh yeah i'm just picking picked up a few examples here there are many other optimizations that have been right here are some examples of these optimizations yeah so this two clarification questions so here you are it's not really solving an optimization problem right it's solving there's no cost function there is a cost function what is the cost function one is of course we want to minimize the number of cars okay that's one second many of these constraints are soft constraints and violating this there's an associated cost and then how do you combine those yeah the linear combination so there's a z3 allows you to give penalties and you can minimize so this is z3 opt z3 opt yeah okay but i don't know finally what we use because i think z3 opt by itself doesn't scale so we just did a binary search okay to that's what we did i think z3 opt am i right z3 opt didn't really scale by itself so we did a binary search and then the second is so that if i understand the theories it's linear arithmetic uninterpreted functions and quantifiers yes yes that's right yes okay thank you you're right so this is the numbers and here is our comparison with the ilp solvers and so we used to be encoded the whole thing in gurobi which is a which is one of the best ilp solvers that's available and for 13 tests it took around 30 minutes and recollect here we are from here you can see we are doing 53 tests and 97 tests so 13 is very less and it's just not so gurobi just did not scale up encoding it in an integer linear program and then we had a so we had one intern aditya interning with us and he believed that these two would do significantly better than satis empty and therefore he encoded in both and so thanks to him we have these numbers and where neither an integer linear programming nor a pseudo billion solver really scaled up for the problems that we have and i believe it is because the integer ranges per se in this problem are very small the integers per se are very small so the largest integer is a date which is goes only up to maybe 500 or 1000 they they're not really large integers and I think when the problem the integers space that you're looking at is fairly small thick sat SMT does a better job of it than and although he said that the only theories we are using are quantifier elimination and all that I think Z3 just reduced most of a thing to a sat and it didn't use any of the theories at least that's what the log seems to indicate so we are not sure whether it employed any of the theories at all and for but we are not sure of that that's what we believe by looking at the logs and yeah yeah so this is I think more of a comment because in my experience for problems like these which are can be just converted to a normal set Z3 actually does not perform well so for example okay in pseudo billion solver you should consider open wbo and maybe if you can let me know the numbers because I am one of the authors so so yeah so yeah yeah we are very happy to share stuff with you so yeah I would love to get these numbers on open wb how it fairs because which one did I use my experience for problems like this which can so open wb itself uses out of the box set solvers like mini set or glucose or something so maybe open wbo with glucose should probably which one did we use Madhukar oh yeah but which one did you do you remember pseudo billion rounding set yeah so yeah we'll be very happy from my experience because Z3 does not scale that good when you can just do yeah so you may be right so we'll be happy to try it out and check whether it works or not so at least this is our finding he is going to counter us on this I know I let me tell you when Aditya came he said this is just not the way to do it you should be doing ILP solvers and or bullions pseudo billion solvers or something but sat solvers is just not the way he said okay do it it may work we are happy if something works better because this is a real problem which we are solving and they are using this tool so the automotive company for whom we are doing this they are using the tool that we have developed using her so we will be happy they will be happy to find a better solution and we are most happy and so the interesting question that comes up is we spent a lot of energy and time finding a good encoding a very iterative process at the end of it we are not even sure which encoding worked which encoding helped the most what encoding didn't help us too much it's some encodings worked sometimes sometimes they didn't work and all that so it's not really clear the question is can this be done automatically so if I can we just say take the same problem but reduce the number of tests to something where even and do a search to find what encoding works for that and hope that the same encoding works for all other when you increase the number of tests so is that is that something that can be done automatically is a question that we have and all our encodings work correct because we had a way to check that the encoding is correct so we had a there was no bugs there so that's a problem that we'll be interested in to find is there an encoding that will be that will work or not yeah so in the manufacturing context typically when the first lot goes right so a lot of tests are put into that very rarely as you progress even anybody utilizes the stability of the production process to eliminate that test and this is a very chronic problem in all manufacture right so I'm happy to see some modeling and I'm from Phillips so yeah so you're right just to add we're not doing vehicles while we do medical devices and since the criticality of the device is so much nobody dares to touch it right and without any data driven judgment I mean it's very difficult to eliminate because then you can be jade sure so those are the risks entirely model will be very very helpful and save a hell of a money and the time if you really prove okay it's not necessary correct absolutely you're right and of course another requirement of these manufacturers is that they will do these tests something will feel so their entire schedule goes for a toss and they want to do it incrementally without affecting the final should release data as much as possible so that's a another requirement that's also part of the tool that we have developed so so those are two applications that I said but these are other applications that we have explored sat SMT for harness optimization card game bridge we are trying to see if we can encode bidding rules using sat SMT one thing that's not mentioned here is we are also another car manufacturer came to us and they wanted to just count the number all automotive manufacturers support users to choose configurations so you can see I want a sunroof I want this I want that or that so they just from a business perspective they just wanted to count how many configurations are they supporting this is so that because they want to make it manageable so they want to reduce the configuration without impacting customer satisfaction and all that so they just wanted to count how many configurations that's on that's something we again did for an automotive manufacturer using a sat counting tool we used hash sat for that then these are worst case time I said there are more more research things that they're not really applied but you are trying to use for worst case execution time of a piece of code and also a scheduling algorithm we are translating those into sat problems and applying it so there's a wide range of applications in which we are using sat and that's the brings me to the end of my talk thank you so any last questions yes thank you for your talk that's very interesting regarding the absolutely on part and I think yes the testing with the rounding set is one thing but there are many others and open wbo is probably also something to consider are the benchmarks available because you know what is really important for software designers is to have benchmarks I know and if you can make those benchmarks available it's or even maybe the description of the initial problem because the way to model it there are many many different ways to do it and the it's typically crucial and the people also from constraint programming who really are interested this problem is typically a constraint programming yes problem and then we have the best constraint solvers currently do automatic translation into sat using a huge very sophisticated encoding but you you have to do it from the constraint from the domain level so you do not do it by hand so you really need to have the constraint expressed at the highest level so yes I would well if it's possible for you to make maybe I mean with fake unfortunately it's not a decision we can take yes it's our customers data so no no but maybe not real data but yeah at least some kind of fake data and real constraints so that would we can check that out and so so I think I agree with on this point that maybe some kind of normalization or anonymization of data so if you can give us like I said it's not something we can even take a call on it's not our data it's not it's not data that belongs to us and so we would but so if there's an intern who's someone willing to intern with us and explore that that's something we can give them access on our premises that's a much easier problem but yes we will check whether it can be done in some form or the other we did try some constraint solver also I thought Aditya tried that also and yeah we tried constraint solving also and where you can express it at a higher level I just don't remember the tool we tried yes yeah we tried one of those I the constraint solver and that also didn't scale up you're right constraint solver gives a much higher level way to encode therefore we were very hopeful and that will work but again this comparison I think is not a fair comparison because I don't think we put as much time in encoding into these as we did into a SAT SMT encoding and maybe several if you put a comparable effort into encoding into this maybe we'll get her but but we are not the first people to find SAT SMT working better for optimization there have been other instances where they have found SAT SMT to be one one key difference though is that something like z3 you can throw a quantified constraint at it yes and that it's heuristicity with the quantifiers but here you can't encode a quantified constraint into Guroby for instance correct so I don't know how you know what was the whether you really needed the power of quantifiers for your benchmarks so we did have quantifiers as you say but they are all quantified over a small oh I see it's all finite finite finite finite it's not over an infinite domain it's just quantified just simplifies the expression it's not if you use pi z3 it just pull up the quantifiers it just instantiates the quantifiers I mean wherever it can okay so I think the interest of time let's head for coffee yeah so thank you thank you once again for your patience and yeah let's thank Venkatesh once again