 IDA has a feature that I happen to really, really like and that is built in support for sets as well as operations upon them such as membership tests and there is actually even a way to do things like set unions and set differences. Now this isn't super obvious and it's not something that most other programming languages even have so it's not really something you look for or try to seek out in most cases. That being said let's get into showing how this is actually done. Now I need to create a file so let's just do let's just do an example program and I can have everything in there. We'll need some text.io stuff so let's bring that in now and I'm going to show this off just with a simple membership test at first. So let's do... I'll use the same example I used in the ad introduction video so that was if 5 is in 1 through 10 and obviously it is and if we run it of course it does say that 5 is within 1 through 10 because it obviously is. This in and of itself is just sort of handy but not super useful it's not really what I'm talking about quite yet. So let me show how to actually assign a name to this to really make it more of a set and not just a simple range and that is actually done through a little bit of an overloaded keyword. If you did watch the ad introduction video you would have saw that membership tests can be done both on ranges and on types. Now we're going to utilize here is that for this purpose a subtype is still a type and if we do a subtype and I'll just call it set and it still works but now we actually have a name associated with this which is handy. Now this is still pretty limited and not what I would really consider sets and the way the way you get a more serious more developed set is through an other 2012 feature called aspects specifically the predicate aspect and so if we do I think we can just leave this here let's do let's do an odd set so it'll be the same range but we're going to put a predicate in here. Now if you're using that specifically and I am here what you can actually wind up doing is just predicate I don't have highlighting for that because it's a not specific thing but otherwise you can use either static predicate or dynamic predicate we're going to have to wind up using dynamic predicate for this one I'll explain a little bit about what each of those is later on in this video but for now just it'll be a dynamic predicate and you write in the code to check for this. Now checking for odd is going to be what odd set and then odd should not equal zero. It's an interesting syntax highlighting bug. Set is oh yeah because I need to change this as well and of course this makes sense because 5 is within 1 through 10 but it is also odd. If we copy this over and this time we may get an even set so this one should evaluate to 2-0 instead of anything other than zero. We'll copy this again and we'll differentiate at this time. Now just to see what happens if we come in nothing because even though 5 is within 1 through 10 it is not even and the predicate there is specifically checking for it being even so you can view the odd set as being 1, 3, 5, 7 and 9 while the even set is 2, 4, 6, 8 and 10. Obviously 5 will be in this one but not within this one. Now this actually isn't the only use for sets. We can do this with non-numbers as well and in fact basically any I know for sure it's any discrete type I'm not sure if it's any scalar type. We'll show off the other discrete which would be enumerations. I'm gonna be doing it with character and then we'll do a little bit of a test to see if it works with any other scalars. So this one will actually just do a character test for now. So again just like with the numbers this isn't super useful yet so let's actually do another subset even though we are using it as a subset we would call it a subtype in that up. So let's just do well now I don't want to combine two ranges at first so let's just do lowercase and then this would be character. Yeah because we're trying to put an uppercase C so if we put in a lowercase C instead this should actually work. So let's combine two different ranges here because that'll be a different way to show off how to use the predicates and conveniently in this case it will actually be a way to show off static predicates and then that gives me an opportunity to talk about that. So for this one we're going to do we'll convert this to the alphabet one and it would be alphabet and character range lowercase a than I should have and let's of course that one shouldn't actually be true. So the difference between static and dynamic predicates is basically with a static predicate you can tell exactly what it is ahead of time that is it is statically evaluatable. It winds up being the case with this specific example because the range isn't going to change you know character is already an enumeration that is established and we're just checking if it was within two different sub ranges of the entire character enumeration. There's no computation going on that can change this. In a way it is kind of like being functionally pure and that the result is always going to be the exact same thing whereas a dynamic predicate usually involves some kind of actual evaluation. That was the case before with the number check or even or odd because the mod operator is in that case intrinsic but is a function that is actually being evaluated which that one is functionally impure but we can't actually guarantee that just because it's a function call and it's possible to have impure functions in height up. This makes it so it has to be a dynamic predicate. Now there's a little bit more actually going on there if you're very interested in knowing the difference between the two it's described in the reference manual but that description alone should cover 99.9% of all situations you find yourself in there. But this shows off membership tests and actually defining sets of you know different styles. Let's show off how to actually do a union now. So if I split this up again in lowercase I don't need the predicate for this so just range. That's pretty much it. The OR operator is union so if you want to define a new name to the union you can put it there otherwise you can just well it's this so just in lowercase or in uppercase. Now this kind of shows off why I recommend actually assigning a name to it because otherwise you've got to duplicate what you're checking for twice and that makes it a little bit error prone plus it's much more wordy than just having an alphabet. So it looks cleaner and it's actually less error prone if you have to tweak anything. Sometimes you forget to change all of the values you're checking but that's a union then we have the difference. Checking for if it's or difference? No no no no wait. We'll check if it's in one but not the other first. So for that if we do and we'll need a static predicate for this one just because of how this is going to work out so I'll play forgot one. That's embarrassing. Don't worry about why this this gets the point across. So yeah we want to check if it's we'll do if it's a lowercase but not about one which I mean we could just define a consonant subtype as well but then that doesn't show this off. So we want to do if C is an alphabet. I believe it's just and not C in vowel. Oh yeah because of the operator preference. So we do it like this. Yeah C is an alphabet character and if we replace this instead with E which obviously is a vowel. You can see that it doesn't actually evaluate this time because while E is in the alphabet it is also a vowel and we're checking if it's not a vowel. But so this is a little quirk that you do need to consider that I sort of forgot about here. The knot is normally a very high precedence operator so it's it tries to apply it first but we need to check the membership first and then apply the knot to the membership check. So just wrap up the membership check in parenthesis before the so that it does that first before the knot. Yeah so this this would basically be a difference too. So if we do subtype consonant we can do it would be consonant. I need to put this after the alphabet. Consonant and alphabet. So we actually have a there's what unions differences and there's one other set operation I believe I'm forgetting. Junctions I believe it's called testing that it's sort of in two different sets. I think that's the one I'm thinking of. That should be pretty obvious in that just one of them isn't actually check one of them isn't actually negated. So if we do capital C instead and in consonant and C capital C is an uppercase BC is there we go. Now let's actually play around with this and see just sort of how far we can take this. First things first I want to see if floats can actually be used here and if floats can then obviously fixed points can as well. So let's do positive so we just do range 0.0 up through no this will need to be 0.0 plus float small up through last and then if we try to do if I don't know 2.3 and let's try this. So a little bit of explanation of what's going on here. There's two attributes that are useful well three attributes that are useful for ranges and one is the range attribute which returns the full range but there's also first and last which respectively turn return first and the last part of the range. In this case since we're only interested in defining a new start for the subtype we only are interested in using the last attribute. The first what we're doing here is because 0.0 itself would not actually be a positive that's would be part of the sort of like natural floats but not positive floats. So what we want to do since we know it wouldn't be practical to type it but we're also not exactly sure what it would be to type out is to take 0.0 and add to it the absolute smallest amount of difference that a float can support on this platform and that's what small is it returns the the smallest difference between values that type supports. So with this we have the closest value to 0 that is not 0 all the way up to the last that the float actually supports so that is all positive floating point types. So let's see if I can also I think I might know a way to figure out if these are positive as well or not not they're already positive what am I thinking to figure out if these are whole as well so I think we do be something like you know what never mind because we've pretty much seen what we want to do anyways so that would really just be me nitpicking the scene how far I can go clearly that is clearly floating point types and fixed point types are actually usable as part of sets as well which is really really handy there's a lot of special definitions of different types of floats like whether or not it's you know infinitely repeating rationals or z-rationals and other stuff like that so this would give yet another way of actually using these. Sure no I believe that's all that would actually be able to be done there is one more membership that I want to test this wouldn't so much be a set but it depends I've seen some people implement sets like this so let's actually do type let's just do set is array I just want to see if this works yeah that one doesn't so yeah I have no reason to think that set operations would be allowed on anything beyond the scalar types and given that it doesn't seem to work with the array yeah I'm pretty sure just anything that is a scalar type so that is any integers, modulars, numerations, floats and fixed points you can use for sets which does pretty much make sense that fits with what you would expect so yeah not not one of the most obvious features but hopefully you can see how this is actually pretty useful especially it makes for some very sophisticated membership tests so what would in many other languages be you know this plethora of is uppercase is symbol is number is even is odd is prime it can actually be just be done through a number of sub types that are used as sets which is very very clean elegant syntax I really like this feature of that so hopefully film this video helpful please consider giving a thumbs up it actually helps a lot with how YouTube does video rankings and helping people find videos the more thumbs up the more YouTube is likely to recommend this to other people so it really helps out a lot also consider subscribing if you haven't already I try to do a lot of these videos I know recently recently at the time of recording this I've been remaking a lot of the old content I did in much better quality it it was kind of yeah before so have a good one guys