what does it take to please God? What is God looking for from us? Now as born-again believers, we all desire to please the Lord, and I want you to think about this. Ephesians 4.30 makes it clear that disobedience can grieve the Holy Spirit.  Here's what Genesis chapter 4 verses 2 and onward say. Later, she gave birth to his brother and named him Abel. When they grew up, Abel became a shepherd while Cain cultivated the ground. When it was time for the harvest, Cain presented some of his crops as a gift to the Lord. Abel also brought a gift, the best portions of the firstborn lambs from his flock. The Lord accepted Abel and his gift, but he did not accept Cain and his gift. This made Cain very angry, and he looked dejected. Why are you so angry, the Lord asked Cain? Why do you look so dejected? You will be accepted if you do what is right, but if you refuse to do what is right, then watch out. Sin is crouching at the door, eager to control you, but you must subdue it and be its master. Now, here we see that the Lord accepted the offering of Abel, yet rejected the offering of Cain. Now, why was this? There are a few theories. One thought is that Abel offered blood, Cain offered from the ground, and so maybe this was a prophetic parallel pointing to the sacrifice of Christ in that God would accept what came from that which was given of blood. Another thing we see in the scripture here is that Abel offered the best portions of the firstborn lambs. In other words, he gave the best of the best. Well, the scripture also by contrast tells us that Cain just kind of gave some of his crops, some of his crops as a gift to the Lord. So the Bible doesn't indicate specifically that these were the exact reasons as to why the Lord accepted one offering but rejected the other, but at least we are given some clues there that maybe we can glean from. What is known, or I should say what is safe to assume is that Cain and Abel knew what was acceptable and what wasn't. I mean, even if we just look at verse number seven here, you will be accepted if you do what is right. The way this is phrased here, it's almost giving the implication that the Lord is saying, look, you already know what to do. You know why your offering was rejected. So even though the scripture doesn't say explicitly that Cain and Abel were given instructions, we can at least infer from some of the language here that they were given instruction. They did understand what was and was not acceptable, but ultimately it comes down to obedience. For whatever reason, God rejected Cain's and accepted Abel's offering. Ultimately, we can conclude safely that it comes down to obedience. Obedience is better than sacrifice. Sometimes we present things to the Lord and say, Lord, here's what I gave up for you. Here's what I did for you. And out of this sense of entitlement, we think that God should just respond in the way that we desire every single time. God is not a vending machine. You can't just put in one thing and expect a very specific result from Him. Yes, we can ask for things in faith. For example, you can believe for healing. You can believe for a specific miracle. You can believe for a specific kind of breakthrough. All of that's fine, Matthew seven, seven, ask, seek, not, keep asking persistently and in faith. But ultimately God decides what He does and when He does it. And so this idea that He must respond to us as we desire, it's just a sense of entitlement that would cause us to think that some have even left the faith because they felt let down or disillusioned because God didn't respond in the exact way that they thought He should or when they thought He should respond. And so that again is coming from this place of entitlement, this place of ego, where we place these boundaries on God as if He has to fit in our neat ideas and as if He has to function between the lines of our expectations. This is just not godly. That is carnal, that is ego, that is selfish, and that is pride to act as if we are the Lord and He is the servant. That's not how this works. So yes, there is something that God requires of us. He has very specific requirements. He asks things of us. There are two extremes here I want to cover. When you give what God does not require, it's legalism. Let me say that again. When you give what God does not require, that's legalism. When you don't give what God does require, that's disobedience. Now, this is important that we understand this because I think between these two extremes, many believers often get caught. When you give what God does not require, that's legalism. For example, I was sitting with the young man who was being discipled and wanted some advice. He was talking to me about this wonderful relationship that he was in with this young Christian girl. They were keeping things pure. They were praying. They were connecting in a godly way. We were celebrating that fact, but he couldn't get this thought out of his mind that he had to give that relationship up. I sat with him and I said, okay, you need to make sure this is the Lord because I want to understand why you think you need to give this up. Is it pulling you away from the Lord? He said no. I said, is there any sin involved in this? He said, no. I said, okay. Did God speak to you specifically? He said, I don't think so. I said, so what is it that makes you think you have to give this godly, fruitful, beautiful relationship up? He says to me, well, I feel like I have to give it up because it would be hard for me to give it up. I thought that's an interesting way of looking at that. He didn't believe that God wanted him to experience something good. He was of the belief that because it was something that brought him joy, that it would have been difficult to give up, that he had to give it up just because of that. I think that's sometimes what we do to ourselves, especially people who are bound by guilt. They're bound by legalism. They're bound by religious ideology. Look, we acknowledge sometimes you do have to give up blessings when God instructs you. But some of us think that inflicting unnecessary emotional pain on ourselves is in and of itself pleasing to God. So sometimes we, as Christians, we think that because something gives us joy, we automatically have to give it up. We think that because something maybe takes some of our time, we automatically have to give that up. That's not always the case. And it would be legalism to say, because this brings me joy, I have to give it up. That's one extreme. The other extreme is when we don't give up what God does require. And this right here is something we need to be careful of, especially because this is where you now get into sin. This is blatant disobedience. So we're talking about what pleases God. Well, it's simple obedience. It's not always going to come down to a formula. It's not always going to come down to an exact list of things that maybe God asked someone over there to give something up and maybe not specifically you. Now in that note, I want to make sure you understand I'm not talking about sin. Sin needs to go all the time. If we're talking about blatant sin, of course you have to repent of that. You have to get that out of your life. There's no excuse for that. That's something you have to get right with God. I'm talking about just sacrifices in general. I'm talking about giving things up that the Lord tells you to give up that maybe aren't necessarily sinful, but you're hanging on to them. Now, do balance this because, again, there are some Christians who will say, well, because I enjoy this, because this brings me joy, because it's something I consider blessing, I have to give it up because God will find that pleasing, well, not necessarily. And that again would be to fall into the category of legalism. Still, I will not give to the Lord that which cost me nothing. Now your salvation is free. Christ paid for that. You have faith in him. Your salvation is free. But as you begin to become a disciple of Jesus, you will find that at times there are things that Christ asks of you that contradict your plans. There are things that the Lord asks of you that go against what you desire. And this is where you find that tension now between your will and God's will. It's Jesus in the garden. Nevertheless, not my will, but your will be done. And we find ourselves in that garden, don't we? Asking God, if there's any other way, please, let me go that route. And sometimes we try to bargain with him, debate with him. Maybe we try to get him to change his mind. The Lord won't do it. And this is where we have to yield. Listen to me. This is where we have to yield. I know that sometimes it's going to cost you. I know that it's not always easy. I know that people may misjudge you. People may mock you because of how you follow Jesus. But you have to give it up if the Lord requires it of you. And this is where sacrifice comes in. What pleases God? Obedience. What pleases God? Trust. Trust and obey. We complicate this. We complicate this. It's as simple as trust and obey. Write that in the comment section. Trust and obey. Whether you're watching live or replay. Type those words out. Trust and obey. Get that in your spirit. Repeat that. You know that when you trust and obey, it simplifies things greatly. Because sometimes we obey, but we don't trust. And we're filled with fear and doubt about having obeyed God. And this is where we need both. Lord, I trust you. Lord, I'm going to obey you. And I know that what pleases you is when I follow your word. I know that what pleases you is when I do what you ask. Mark 12, verses 30 and 31.  The second is equally important. Love your neighbor as yourself. No other commandment is greater than these. So all of the law and the prophets, everything that God requires of us can be summarized here in these powerful words. In other words, love God with everything that you are.   And you know what Jesus said, if you love me, you'll obey my commands. Trust and obey. This is the simplicity of the Christian life. To do it any other way is to complicate it. To do it any other way is to bring tension and fear and anxiety and doubt and confusion and religion and superstition. Any other way you'll get tangled up in your own emotions. Any other way you'll get tangled up in your own thought patterns. Trust and obey. That's how you do this. And you obey because you love him. You obey because he's the Lord. You obey because he's the savior of your soul. So I want to give my all to Jesus. And that's all he requires of you. Trust and obey. And you leave the rest to him. You trust and obey. People will mock you. People will misunderstand you. You'll have to give some things up sometimes that you don't want to give up. You may find yourself in places that you don't want to be. You may find yourself in situations that make you scratch your head and say, God, what are you doing? I don't quite understand this. But you trust and obey. And it is in that childlike faith, not child, not being childish, being childlike, to where you place your faith totally in him and you let him take you by the hand and guide you day to day in this walk that you have with him. And you say, Jesus, I want nothing else but you. I trust and obey. And that's how you please him. That's what it takes. It's a father in the name of Jesus. I pray for your people now. And I ask you to touch their lives in a fresh way. Give them the grace and the strength to please you through obedience and trust. We give you the honor and the praise, Lord. In Jesus' name we pray. And I want you to type it in the comment section if you believe it, type Amen. If you enjoyed this message, be sure to leave a like and let's you and I stay connected. I want to do more of these with you. So make sure you're subscribed to my channel so you can get the alerts and click that notification bell when you subscribe so that you can get the alerts of when I go live. I'd love to spend more time with you and the word and prayer and so forth. It'll be a great time together. And now I want to challenge you.  And you've been watching for a while. You've been enjoying the content. You like what you see. I want to challenge you now to get involved with what we are doing as a ministry. Listen, your giving is not tied to your healing. Your giving is not tied to your deliverance. Jesus will heal you whether you give or not. Jesus will deliver you whether you give or not. I believe that that was already purchased on Christ's cross. And that we freely give. But there's also this responsibility that we have as believers to support the gospel. And the Bible is 100% clear that as we sow, we reap. Now generosity is one aspect of stewardship. It's not the whole picture. So, you know, just because you give doesn't mean you're magically going to come out of all your financial trouble. But it is one of the tenets of stewardship that ultimately amounts to increase. And so I want to challenge you to sow. I want to challenge you to give into this work and help what we're doing. We don't give to get. We give so that the gospel can go forward. So if you've been blessed by this ministry and you want to see others blessed by this ministry, then will you right now go to David Hernandez ministries.com slash partner and sign up to become a monthly ministry supporter so that we can continue to do what we do as a ministry. You can also give a single gift by going to David Hernandez ministries.com slash donate. I appreciate your support. I love you. And I pray for you. And until next time, remember nothing is impossible with God.


Well, it's one of the hottest tickets around and one Bemidji business just gave out two tickets to Super Bowl 52. Through a special promotion, Bar 209 in downtown Bemidji qualified people throughout the NFL season for the grand prize. There's only a couple of days ago that Kyle Schuster's name was drawn for the big honor. Schuster says he was surprised when he found out that he won the tickets and he's happy he can share the Super Bowl experience with his father who is a big football fan. I was really excited. My dad was the one who actually took the call, so I wasn't actually the one who heard it, but I was really excited when I heard what my dad told me, so he's a much bigger football and Vikings fan than I am, so I can only imagine he was very excited. The ticket giveaway was thought up by the Bar's manager throughout the season for every Vikings touchdown, everyone's name in the Bar would get entered into the drawing. The Bar would made the contest extra special, was awarding the prize to someone who was from the area.  Just when I saw the 218 number on the actual ticket I drew, it was exciting. I knew that it was someone local, someone that we might know, someone that familiar face in the Bar, so that was definitely special that it was from Bemidji. Bar 209 said they probably won't give away Super Bowl tickets again next year, but they will likely do the promotion again, but for a Vikings game instead. If you enjoyed this segment of Lakeland News, please consider making a tax-deductible contribution to Lakeland PBS.


Welcome back to our lecture series, Math 3120, Transition to Advanced Mathematics for Students at Southern Utah University. As usual, I'll be your professor today, Dr. Andrew Misseldine. Incompetent torques were often are faced with enumeration problems involving partitions. More specifically, given a set A and some partition P, we want to count the number of classes inside of the partition. So if A is our set and if P is our partition of the set, what we often want to do is count the number of cells in the partition. That is, we want to find the cardinality of the partition itself. How many classes are there? And the way we approach as often is by looking at elements inside the set and using that to help us better understand the partition. Because after all, if you look at a class, you could take an element in that class, and they're probably connected to each other by some relation, like there's some notion of sameness, like these elements are in the same cell for some reason. And so you might look at a typical element in a class and use that to try to count how many classes you have. But the problem you can get is over counting. Over counting is a problem when you count the same class in a partition more than once because you took two different representatives of the same class and counted them more than once. To try to illustrate that, let me actually take a very simple classic problem from polynomial theory and consider how one can over count the potential rational roots it has. So consider the polynomial 2x squared minus 11x minus 6. By the so-called rational roots theorem, we actually have a list of potential rational roots for that polynomial. Now, the rational roots theorem tells us that all of the possible rational roots of a polynomial can be found by taking the divisors of the constant term and divide them by the divisors of the leading coefficient. So if you take all the divisors of 6, which would be 1, 2, 3, and 6, and you divide that by all the possible divisors of 1 and 2, and these are integer divisors, so they actually could be plus or minus, plus or minus 1, plus or minus 2, plus or minus 3, plus or minus 6. You have to take all the possible divisors of 6 and divide them by all the possible divisors of 2.   And so this gives us the list of potential rational roots. The rational roots theorem then says that if this polynomial has a rational root, it's among these numbers I've listed on the screen right now. And therefore, if you're going to start looking for them, you could start testing these numbers. And so like a college Auser student might then proceed to start doing synthetic division on the polynomial, using these as your potential roots there. But how many potential roots did I list here? It's tempting to say that there are 2 times 8, that is 16 potential roots in this situation. Where did the 2 times 8 come from? Well, 2 comes from the fact that every choice is a plus or minus. There's the positive choice and the negative choice. Sure, you can go with that. But this 8, the temptation there is that, oh, 6 has 4 divisors, 2 has 2 divisors, and of course only counting the positive divisors right now. And 2 times 4 gives you 8. But when you look at this list, there are not 16 possibilities. Now again, it looks like 2, 4, 6, 8, 10, 12, 14, 16. It looks like that's the case. But when you look at some of these, look at this one, plus or minus 2 over 2. As a fraction, 2 over 2 is the same thing as 1. And so the potential root of 1 actually was listed twice on this list here. Same thing if you look at 6 halves. 6 halves is the same thing as 3. And so if I list all of these potential rational roots, it's tempting to think there's 16 possibilities. But these ones actually count the same rational number twice. And therefore it's not going to be 16 because we actually took away 4. There's only 12 potential rational roots in this list because some of them got listed more than once. And this is something important to remember about rational numbers. I can take fractions like 1, 1, 2 halves, 4 fourths, etc. These are all the same rational number, even though they're different fractions. So if I list a bunch of fractions, I might erroneously think that different fractions give us different rational numbers. But clearly, different fractions can give us the same rational number. And so if I write different fraction that represents the same rational number, I have to make sure I only count that rational number once. This is the fundamental problem of over counting. We have to make sure that different representatives actually represent different classes and that we don't take the same or we don't take different representatives for the same class. 0 1 always must be wary of this in combinatorial problems. And this comes into play when you start thinking about partitions. Okay, so now this gets us to the titular topic of this video, the so-called division counting principle. This is in connection to the multiplicative additive and subtraction counting principles that we've seen previously. If A is a finite set with a partition P, remember a partition is going to be a collection of subsets that cover everything in the set and which none of the cells overlap each other whatsoever. So we have a finite set with a partition, the exact problem we were talking about earlier. If each class in the partition called C has the exact same cardinality, then the cardinality of the partition is just the cardinality of the set itself divided by the cardinality of a single class. If everyone shows up with every class shows up with the same size, then we can divide the total set by the size of a class and that'll give us the number of classes, number of representative classes in the partition. Let's utilize the division principle in the following example. How many anagrams can be formed from the word rearrange? Now just so you're aware, an anagram is when you take the letters of a word, you rearrange them and then form a new word. And so appropriately, we're going to look for rearrangements of the word rearrange. It's kind of fun little example here. And when we consider these anagrams, we're going to look at all real and imaginary ones. That is to say that when you excramble up the letters, it doesn't necessarily have to make a new word. So we could do something like if I just were to swap around the letters E and R, we would get E, R, and then let's keep everything else the same. And so this would be an anagram of R-range or something like that. I don't even know how you pronounce that. It's not a word that I'm aware of, but that would be considered a rearrangement. You can swap up the letters and we get an anagram. How many possible anagrams can you get here? Now, if I give us a much simpler question, like if I were to take the word like say cat, three letters here, how many anagrams could you get there? You can get things like act, right? TAC. But again, it doesn't actually have to be a word. You could take CTA. That would be considered anagram here. In this situation, when there's no repetition in the letters, then the number of anagrams is going to be three factorial because you have three options for the first one. Then you have two options for the second one because you can't repeat the letter you had. And then you have one option for the last one. And so if you have a word with no repeated letters, the number of anagrams is just going to be in factorial. Now the word rearrange other than a pun was chosen because there are some repeated letters in this word. The word itself contains nine letters, in which case we have three letter R's. We have two letter A's. We have two letter E's. We have one N and we have one G. To construct each of the anagrams, we need to assign a letter to the first position of the new word, the second position of the new word, the third position, etc. If we suppose that each repeated letter is actually distinct, because when you look at these letters here, we have, here's my three R's. If I were to rearrange the R's, you couldn't tell the difference between them because they're all the same. So what I'm going to actually do is I'm going to pretend for a moment that the R's are actually distinguishable. I'm going to put a little mark that only I can tell about, right? So I'm going to call them R1, R2, R3. Then if I were to rearrange the R's, because I've marked them in a way that only I can tell, then I would be able to tell the difference as they get moved around because I've now made them distinguishable. So therefore, words like the original word, rearrange, R1, E, A, R2, R3, A, N, G, E, like so. That's one rearrange, but then another anagram could be R2, E, A, R3, R1, A, N, G, E, right? Because of the marks I have put on the R's, which make these now distinguishable, you can tell how I've rearranged the R's, okay? So I'm intentionally making my identical elements distinguishable, so I can tell how I rearrange them. Because if you do that, if you do that for each of the letters, so let's say something like the E's, there's two E's after all, we'll call this E1 and E2. So then in an anagram, you can tell if they got swapped around or not. And then we'll do one last one with the A's. If I tell a difference between the A's, maybe you switch them around, maybe you don't. If you have little markers on them, I can tell how they are moved around. Then in that situation, if you've marked all the letters, there's nine letters total, then much like we did earlier with the word cat, if I can tell the difference between the letters, I can rearrange them. There's going to be nine factorial anagrams of this word rearrange. But that's only if you have the markers, if you have the marks attached to them. Now, nine factorial is going to be much too large for our problem here, because in all reality, we shouldn't be able to tell the difference between the A's, the E's, and the R's. They all should be indistinguishable. And this is where the division category, or the division principle comes into play here. So if you were to consider just a rearrange one where you only change the R's, so we take R1, E, A, R2, R3, A, and G. Don't even worry about the A's and the E's marked right now. And we'll take the R, we'll switch them around like we did before, like this. These words should be considered the same word as an anagram, even though we distinguish between them, no one else should be able to distinguish between them. So these are going to be considered the same word. And so what we can do is, if we take as set A, we could take as the set A all possible anagrams with distinction, that is, we've marked the letters so that we can tell them apart. If we take A to be the set of all anagrams with distinguishable letters here, we put little marks on them, then what we can do is we can form a partition on that set here. The partition, this is our partition on A, where words are considered equivalent, where anagrams are together, they're together if they only disagree on the R's. We could do something like that. So we take all of the anagrams that we could form from the word rear range, and we form a partition where two words are considered equivalent. If the only difference between them is how we changed the R's, like we had on the screen a moment ago, where we changed only the R's, everything else was the same. And then in that situation, then if we want to count the size of the partition, this is going to be the size of A divided by the size of C. Because regardless of what the anagram is, each of these classes is going to be the same. If all the other letters are still considered distinguishable, you only care on how the R's disagree with each other, all of those classes sizes are going to be the same. So you end up with nine factorial on the top. And then how big is each of the classes? Well, like we wrote them on the screen a moment ago, rear range, one possible representative of this class would be if they're in the order one, two, three. Another possible order would be like two, three, one. You could take one, three, two. You could take three, two, one. You basically, it comes down to how many ways can you rearrange the R's? In which case the ways you can arrange three R's and a line would be three factorial. So our partition here, basically what it does is it's going to forget the distinction of the R's. If we take the total number of words here, and we, which is nine factorial, divide that by three factorial, it forgets the distinction of the R's. But we also have distinctions of the E's and distinctions of the A's. And so if we take B to be the set of anagrams where E and A are distinguishable, but R is no longer the case, then we see that the cardinality of B is this number we did before. It's nine factorial over three factorial. But we can put a partition on this one as well. What if we put a partition so that the partition here forgets, it forgets the distinction of the E's. So like with the word we look at earlier, what if we can tell the difference between the E's? How many ways can you arrange it? One and two, you could do two and one. Those are the only possibilities. That's actually going to turn out to be two factorial. In that situation, your partition P, it's going to have the cardinality of B. But then each relation you put here, when you forget the E, there's two factorial possibilities. And so with B early, you get nine factorial over three factorial and two factorial. We've now forgotten the E's and the R's in that rearrangement. You have to do it also for the A's. And so in the end, the number of anagrams we're going to come up with is you end up with nine factorial over three factorial, which forgets the R's. You divide by two factorial, which forgets the E's. You then get also a two factorial, which forgets the A's. And so ever since we made the elements distinguishable, we can forget the distinction by using a partition on the set of possible anagrams that do have the distinctions. And so by dividing out each time these equivalencies, we're then forgetting the distinctions. Now, to be fair, there are two other letters. There was N and G, right? If you divide by one factorial, you forget the distinctions of the N's, which of course is just one. And then if you forget the distinction on the G's, that's also one factorial. You'll notice that three plus two plus two plus one plus one adds up to be nine. And this number right here gives us the total amount of anagrams here. And it's curious that while we wrote it as a fraction, this is actually equal to a integer, right? Nine factorial would look like nine times eight times seven times six times five times four times three times two times one. Three factorial is three times two times one. Two factorial, two factorial, one factorial. You can see some things canceling out. Like the three factorial will cancel with that. Two and two goes into four. And so you end up with nine times eight times seven times six times five. And that, of course, is a falling factorial. That's more of a coincidence in the situation. You end up with 15,120 possible anagrams. I wrote that incorrectly, 120 anagrams. But as we often see with comic torques, the number we care about is this one right here. The formula, the general formula of where the number came from. And so the formula we saw just a moment ago, I want to generalize that. And so we're going to create a new symbol, which is known as the multinomial coefficient, the multinomial coefficient. It looks like use the following notation. You put these big parentheses here on the very top, you write a number N. And then on the bottom, you're going to write a sequence of numbers separated by commas. And there is no fraction bar between them. There's no line there. One just kind of floats on top of the other. And this symbol, known as the multinomial coefficient, is of the form N factorial. That's the number on top. And then the numbers on the bottom, you're going to get a product of factorials in one factorial, in two factorial, in three factorial, all the way up to NK factorial. And these numbers do satisfy certain conditions here. So for example, the sum of the NIs has to add up to be N itself. So N1 plus N2 plus N3 up to NK is equal to N, like we saw on the previous screen there. And so for example, on the previous screen, the number we were looking at was nine, three, two, two, one, one. Sometimes the numbers one are omitted and you just write it like this. You can get away with doing that. Basically, if your number doesn't add up to be the number on top, then you just take what's left over to make sense of it. You really should put in the ones there just to avoid any ambiguity whatsoever. Sometimes people drop it. I think it sort of can lead to confusion and notation. So I would encourage you include the numbers there. This number right here, N, suppose you have N distinct, excuse me, you have N objects that are not necessarily distinct. So like in the letters we saw before, we had nine letters, but some of them were the same. We had R's repeated, E's repeated, A's repeated. So we have N possibly in distinct objects there. N1 of them belong to the first type, N2 of them belong to the second type, and there's K types total. So basically what we're saying here is you have some type of partition on your set N for which there's K classes in the partition. There's N1 things in the first cell. There's N2 things in the second cell, N3 things in the third cell, up to NK things in the Kth cell right there. Then the number of ordered arrangements involving these N objects is going to be this multinomial coefficient. So to give you a quick example of this, how many different vertical arrangements are there of eight flags? If four of the flags are white, three of them are blue, and one of them is red. So the idea is we have these flags we're going to put in a line here. So we have eight flags. Did I get up to eight yet? Yes, I did. So we have these eight flags we're going to put in a row. Four of them are white. We can't tell a difference between the white ones. They're all the same. Three of them are blue, and one of them is red. The number of arrangements of flags we have is going to be this multinomial coefficient eight. On the bottom, it's eight, choose four comma three comma one. The numbers on the bottom four plus three plus one adds up to eight. And therefore the number of possibilities is going to be eight factorial over four factorial times three factorial times one factorial. If you drop the one factorial, that's perfectly fine. Be aware that this number, you can simplify it and it's going to turn out to be 280 possible arrangements of the flags. But it's the calculation of this multinomial coefficient, which is a consequence of the division principle we saw on the previous slide. Now it does beg the question, why is it called the multinomial coefficient? Well, admittedly, multinomial and polynomial, they kind of feel like they're synonyms. And for the most part, I would say yes. The multinomial coefficient, it gets its name in relation to a forthcoming theorem, which we will call the binomial theorem and the binomial coefficients, which you may or may not have seen that before. This is a generalization of that result. The multinomial theorem is the following. In the multiplicative expansion of a multivariate polynomial, that is a polynomial which could have lots of variables. And that's why we're using the term multinomial here as opposed to polynomial. There are multiple variables, multivariate, multiple variables in this polynomial. The variables we're going to call them without the lack of better names, x1, x2, up to xk. So if you have like a variable, a polynomial of three variables, you might call it xy and z, but as k could be arbitrarily large, we'll just call it x1, x2, xi in that situation. If you take, if you were to foil out the expansion x1 plus x2 plus x3 up to xk to the nth power, then the coefficient of the monomial term where you take the product of xi to the nth i power, that is the coefficient of xi to the n minus 1 power, x2 to the x, to the n2 power, x3 to the x, to the n3 power, all the way up to xk to the nk power, the coefficient of that monomial in this polynomial expansion is exactly this number right here, the multinomial coefficient. And to see that, well, let's think, how does one produce this monomial in the foil? Like if you foil this thing out, how do you do it? Well, because multiplication is both commutative and associative, it basically comes down to how many ways can you grab in one many x1's and how many ways can you grab in two many x2's and how many ways can you grab in k many xk's. Well, in the original foil, you can tell them apart, this x1 came from the first factor and this x1 came from the third factor. But when you put it all together, you've kind of forget the ordering, that's the exact problem we were seeing before. And so the way to produce this monomial here is you're looking for ordered list of variables x1, so that x1 shows up in one times, x2 shows up in two times, x3 shows up in three times, etc. But then by the theorem from the previous slide, we see that the number of such ordered strings where repetition shows up exactly in this prescribed manner, this is exactly what the multinomial coefficient counts. And so that then solves this problem and thus also guarantees the name of this problem right here. So let's apply this. Let's imagine we have the multivariant polynomial 2x cubed plus y minus z squared, and we raise that to the 100th power. That would be a massive thing to foil out. But what I can tell you, I can tell you what the coefficient of x to the 99 times x to the 60th times z to the 14th is going to be. And how we do that is we have to figure out how do you produce this right here. Now notice y is the simplest one here because it's x1, it's just a 1. If you're going to get y 60 times, that means your n2 is going to equal 60. Well, how did you produce x 99 times? Well, if you have x cubed here, every time you grab an x, you're actually grabbing three x's. And so to produce 99 here, the idea is you just take 99 divided by 3, you take 33. And so the number of times you choose x is going to be 33 times. We have 33 times for the x cubed. We have 60 times for the y. How are we going to grab the z squared? Well, we basically can figure out what we have left over here, right? In order to get z to the 14th. Well, since you only can get z multiples of z squared there, you're going to have to grab z squared seven times. And do notice that 33 plus 60 plus 7 does actually add up to be 100. So n1 plus n2 plus n3 is equal to 100. So that is a possible way you could foil these things out. So the coefficient of this thing is going to look like the following. You are going to have the multinomial coefficient 100, choose 33, 60, and 7. But there's also more to it as well. Every time you grab an x cubed, you're going to get a multiple of two. So we actually get two to the 33 power. Every time you choose a y, you get a multiple of one, no big deal there. And then every time you choose an x, you're also going to get negative one. And you get negative one to the seventh power. So when we throw all three of those numbers together, we actually get that the coefficient will be negative two cubed times three times 100 factorial over 33 factorial times 60 factorial times seven factorial. And that number is approximately negative 2.201 times 10 to the 45th power. It's a huge number. You cannot possibly get that number by just listing all these possibilities. But using common torques, we can predict what that number is going to be by these formulas. Now, another example I do want to mention before we close this video is what if you want to take x to the ninth, what if you want the coefficient of x to the 99th times y to the 61st times z to the 13th, right? I want you to notice in this situation, this is not a possible one you can create. In particular, if you look at the z to the power of z there, how do you get a z to the 13th when you only have as an option z squared? Since two is an even number and 13 is not, there's no possible way you can get that in this. And so in that case, the coefficient is going to be zero. So if it's impossible to create it, your coefficient is going to be zero. But if it is possible to create it, this multinomial coefficient will help you in that calculation.


There was one child who was probably too small for me to be even asking this question now that I think about it, but this can't have been older than seven, came out with the most violent, terrifying, genuinely bone-chilling method of assassination I've ever heard, and even I, as Brian, was genuinely terrified. And I said to the grown-up that this person was the person, excuse me, is this your son? Yes, yes, congratulations.  I imagine you are very proud and his teachers are very worried, and I have never forgotten it since. It will haunt me until the day I die. It was involved, this might not even go on the channel, you're going to have to do a lot of bleeping here. We'll see. But it was to do with making them drink to the point where they would all over their clothes and also on the floor.  Doctor Who, Brian, audience member, you have successfully traumatized me, all the respect in the world to you.


Title 42, tariffs on China. I mean, there's— Title 42 is a public health—is a public health requirement, a public—because we're in the middle of a pandemic, which, by the way, we would have made progress on had the former president actually addressed the pandemic and not suggested people inject bleach. So I think we're in a bit of a different place. I'm happy to discuss more examples. I think it's—people be pretty hard-pressed to argue that the president has taken any aspect of the former president's playbook and used it as a model of his own, had the former president actually addressed the pandemic and not suggested people inject bleach.


Hi, my name is Paul Albert and on behalf of my colleague Terry Wheeler, I'd like to do an update on reciter, something that I've presented before at CNN. Okay. So, reciter is a powerful NIH funded publications management system. It's designed for academic medical centers or institutions. Here's how it works. We use institutional identity data to create a scholars identity. We retrieve candidate articles from PubMed. We use machine learning to estimate the likelihood a given scholar wrote a given article. And then we collect feedback from faculty and librarians. There's a set of web services built into reciter that syndicates the data with downstream systems. And then the biggest changes that have occurred since the last time I presented relate to the the web application where you can output reports and conduct bibliometric analyses. These are the components and ecosystem. So on the top there you have institutional identity systems and these are used to construct the profile. And then you can see into a reciter application, which is typically installed on AWS, but you can still locally as well. There's a separate service which integrates with PubMed. And it takes data from PubMed and then formats it in JSON and has some nice optimizations there. The reciter is displayed in the publication manager web interface data from eyesight, which is NIH is bibliometric service is fed into reciter as well. And then the data from reciter is exposed to downstream applications like our Vivo profile system department lab websites and our faculty review tool. So here's useful identity data about our people. So here's, here's one example, and all these data can be leveraged in order to make high quality article recommendations. Here at while Cornell we monitor output by 20,000 people, I think it's like 21,000 now, mainly academic appointees, especially full time faculty of which we have 2200 postdocs. We have our doctoral students publications, residents for our affiliate hospital, and then members of our clinical and translational science center. So now I am going to hop on over to reciter so I can share with you what the user experiences like. So Dr. Leiden. Okay, so here's how Dr. Leiden might curate his publications. There are suggested publications here, and then users can accept them and they go into the accepted queue.  So this is, this is the evidence score, a score of 10 indicates high confidence. And then if someone else like a librarian is trying to judge whether this article was written by Dr. Leiden, they can click on the show evidence and all the evidence is contained here. Okay, so that's kind of old hat. What's new though is the reporting interface.  And then you only want last authored publications. You want to click search. And so we have 172 articles, and now I can export to our TF. So it's essentially a Word document. And then I go into Word. And then all the, all the names are bolded. And so we have a heuristic which matches people to author position. One thing. And you know it can actually print out like several hundred publications. At scale. So if you wanted, if you had like a couple hundred person identifiers, these are all members of our Cancer Center. So I'm going to grab these, these IDs and go back to find people. I'm going to paste all them in there. 214 people. I'm going to click on create reports. And this generates a report of all publications by all those individuals. I could further filter down by on, you know, author position or whatever. Or I can sort by like what are the most impactful publications according to NIH. All these data can be output in the context of a CSV or Excel file. So you can get an authorship report or an article report. So that's, that's useful. And then there's also the. I want to show you the bibliometric, the bibliometric report functionality as well. I'm going to go back to Dr. But search. So here's Dr. Wyden. Here h index is listed in each five index. I can click on generate bibliometric analysis. And then it's actually here and it's, it generates, you know, pretty, pretty instantly really instantly. So what we're doing here is we're outputting in a word documents. The most impactful publications with some groups by cases where Dr. Lyden's first or senior author position, or where he's any position. And then at the top here, this is a, this is a summary statement regarding how Dr. Wyden ranks relative to peers. So that's what this, that's what this NIH percentile is. And I won't spend time going into that. And then we also rank Dr. Lyden compared to peers that share the same academic rank. And at the bottom here, you can see that those that each index and then you can see an explanation of what all I just described. Another kind of nice functionality we've added is the ability to send emails, notification emails. So there are two types of notifications. One is when an article has been accepted on your behalf. So your faculty at someone else accepted one of your publications. And then the other case is where someone has. I'm sorry, when there are pending publications for you, so there's a suggestion, and you need to provide feedback on it. And this is what the notification looks like. We allow users to manage what that minimum evidence score for their notifications are so if they only want to get the high confidence notifications they can do so. Okay, so that that takes us through to that takes us through what I wanted to share with you. I will say this is for our users with this application is only available inside the network, our network at the moment, we have different roles. I want to give credit to all these individuals I want to also give credit to the people who funded us. Okay, so that's it. If you have any questions, feel free to follow up with me at my email listed there, check out the repository check out the paper. Thanks very much.


Welcome to the session entitled Field Report, setting up a software product line architecture based on Zephyr. This is part of the OS dependability track of the open source summit. I am Gregory Shu from Legrom Incorporated, and I will be sharing my learnings from using Zephyr as the basis for a secure IoT device software product line framework and architecture, composed primarily from open source projects. Don't worry if you're not already familiar with the software engineering institute's research into software product lines. I will be reviewing that too. By request, the presentation given at the 2021 Zephyr Developer Summit is also being presented here. The ZDS 2021 session was given only 30 minutes for presentation and working group discussion. Here, in the 50 minutes allotted, we have time to get into deeper explanations and context for each of the things, relevance beyond Zephyr based projects, and the envisioned path forward on to the presentation. In the late 1990s, Gula Packard management made a strategic decision to restructure the desktop inkjet printer development to reduce expenses and improve efficiency. The decision was to change the development paradigm from leverage and potential reuse to reuse and extend. My printer project was severely impacted by this, required to deliver a hybrid implementation of functionality from old and new firmware architectures. Internally, we jokingly called this the platypus architecture because the implementation was rather ugly, solid, but unmaintainable. That was the beginning of Gula Packard's Owen printer from our cooperative. A hall of fame example of a software product line and was wildly more successful than anyone involved ever expected. With the onset of IoT security regulations and many years of experience previously working in that software product line, my attempt to set up a new software product line from the ground built upon the Zephyr ecosystem proved largely promising. But a paradigm shift is still needed. What is a software product line? It's worth looking at carefully. Here's the definition provided by the Software Engineering Institute. A software product line is a set of software intensive systems sharing a common managed set of features that satisfy the specific needs of a particular market segment or mission and that are developed from a common set of core assets in a prescribed way. This is a new application of a proven concept. It's not a new concept. In 2008, it was considered an innovative growing concept in software engineering. It actually first came about. The early pioneers in it seemed to be doing it in the late 90s and early 2000s. Software product lines involve strategic planned reuse that yields predictable results. It's really important to understand what a software product line is not. We are not talking about clone and own, a single system development with reuse, one where modifying code is necessary for the single system only. We are not talking about fortuitous small grained reuse, just grabbing reuse libraries, containing algorithms and modules and objects or components. We're not talking about just component-based or service-based development, selecting components or services from an in-house library, the marketplace or the web, with no architectural focus. We're not talking about just versions of a single product, rather simultaneous release and support of multiple products. I got to see the entire generation of HP desktop In-Chat printers get delivered out of this code base. We're not talking about just a configurable architecture. It's a good start, but it's only part of the reuse potential. And we're not talking about just a set of technical standards. Those constrained choices without an architecture-based reuse strategy. Where has a software product line been used? As you can read on the slide, there's a variety of places. Successful software product lines have been built for families of, among other things, command and control ship systems, pagers, medical devices, consumer electronics, billing systems. If we look in the linked slide deck, you will find a number of companies inside of there, even at that time, that have successfully delivered software product lines. Some of which are very well-known names, including Bosch and NASA, Rockwell Collins, if you're familiar with automation, Siemens and the US Army. I mentioned this a moment ago, innovators and early adopters have already demonstrated the feasibility and benefits of software product lines, even by 2008. Short list of early adopters includes Hula Packard. And by this point in time, the Software Engineering Institute and others have tried to lower the adoption barrier by codifying practices, writing case studies, perfecting methods useful in product line approaches and engendering a software product line community. Even back then, many organizations were handsomely achieving their business goals using a software product line approach. I'd like to share with you a little bit more about my experience from that early adopter kind of base. The Hula Packard Owen firmware cooperative was voted into the Software Product Line Hall of Fame in the first session of that conference. It is still going on after, what's this, 23, 24 years. I got status update a couple of months ago that yes, it is still alive and well. It started out targeting IoT products requiring to run seven plus years without a power cycle. So this is just not your everyday product. Well, actually it is. It was largely driven by fax machines. The first seven generations, which were delivered on largely a year cycle, were designed around using only in RTOS on a custom SOC with 32-bit ARM microprocessors. Successive generations extended to a multiprocessor system running Linux and in RTOS. Some of this might sound familiar from any of the other embedded environments. It eventually involved into a continuously integrated repository, live updated by developers across the world. We actually had, that I know of, at one point 400 firmware developers working live on changes that were getting integrated into the main branch. And it was active all but about two hours a day. This grew beyond anything that we'd ever imagined and expanded beyond printers and scanners. How successful was it? Well, that just is the breadth. I'd like to share a story with you. So I was directly involved for the first seven years of the software product line and created derivative products for the industrial space over the next nine years. How effective was this? About four years into the software product line, late in the product development cycle, HP management told me we are creating a new model printer for a specific market. This requires one new feature in firmware and supporting a new combination of existing hardware. The first prototype of the unit would be on my desk in an hour. And I'm the product integrator and new feature developer lead. Along with everything else, I need to deliver this in the same product generation. So I started pulling things together and configuring the project. I ended up being very disappointed in what came next. How long do you think it took me to get functionality complete and fully integrated firmware image other than the new feature? Three weeks? One week? One day? Would you believe 30 minutes? It was ready with the correct model numbers and brands and feature configurations before the first mechanical prototype arrived on my desk. So much for job security. I knew it could be that easy to support a new product, but I hadn't expected that we'd already arrived. Why was I disappointed? I had to ask myself the question, now what? The new feature took a few months to develop, but that experience of everything working together because we designed it to work together left a lasting impression. So I changed companies. I'm now working in commercial building control systems, lighting control, distributed systems that are deployed in public and private areas. And we're now having to confront security. So security takes a new rigger on firmware development than we've been used to in the past. I had the opportunity to evaluate how if we're gonna change this code over to being secure code, we're gonna be able to do that. We're gonna change this code over to being secure code. What else can we take advantage of at the same time? So I took some time and I evaluated and attempted to use Zephyr as the basis for a software product line. But how did I do that? You're gonna find Zephyr specific details listed here. One was I started with reuse and extend as the paradigm. So we're reusing the Zephyr ecosystem and choosing supported options inside of that regarding what's the topology of the repositories? How do we tie into the build system? How do we configure and adjust code for the different variation points that we need on there? What else? We don't copy the code. We wanna keep the history on there. Did I create internal forks? Yes, because I anticipate there would be a point where in each repository, I will need to tweak something or isolate particular changes. And so I forked all the open source stuff, made my own branch inside of that, migrate stuff over, merge stuff over as appropriate and try to absolutely minimize what I put in my forks. Repository organization. What are we end up doing at this point? Following the ownership and the licensing that's available, what is proprietary, what is cross licensed, what is open source licensed. I ended up with, oh, more than 50 repositories that we're building together for this. One of them contains all the proprietary content and it contains the manifest of which repositories and which shaws at which repositories, branches and commits are being seen by the build system and being configured against for building the product. So we have one of those for all of our proprietary stuff. The open source and the commercial repositories have been extended to be Zephyr build system recognized modules. Inside of each of these extensions is glue code, APIs, tests, samples, documentation and manifest if needed for isolated development and verification of the extension. And all the Zephyr and Zephyr forks with already set of module repositories also get brought in. The, so we're really focused on reusing and extending this. All the configurable subsystems and drivers contain all the functionality. The project, because we're gonna be building multiple products out of this and whatever is the source code tree that is product specific. The goal is it has no functionality in project unique source tree. In Zephyr main function actually gets called after the entire OS initializes and it is left up to the top level application. In this exercise main is intentionally left empty because I don't want to copy any code between projects. I wanna reuse, live reuse the same code. What else do we do? I check to make sure that it can support multiple manifests and figure out how to do that because there are multiple forks of Zephyr and we need to be able to have part of our products be built off of one and part of our products be built off of another. The reason for that is these forks are seem to be provided by hardware chip vendors and when we change chips, we may need to tweak and change forks but a lot of our application layer proprietary protocols and all that kind of stuff needs to say the same. The workspace is that collection of repositories and we have our own documentation. We need to capture that documentation in our overarching repository, the manifest repository. We chose to parallel the Zephyr documentation structure and tools and the documentation structure is used for generating webpages. It's used for generating PDFs. It is also used in Zephyr or will be used in Zephyr for generating traceability tables of requirements. So the goal was we're attempting to do all of these things and really build our software product line as an extension and application if you will of the Zephyr ecosystem. Now, that was the goal. How do we measure this? The Software Engineering Institute gives us a table already of one of the costs of a software product line and as you can see on the left, there's assets that are identified and what are the costs that are involved over single product focus development. Creating and maintaining a software product line is not free. But it is frequently more efficient overall than maintaining separate implementations. This includes the necessary business support and alignment that the governance structure that are essential parts of the software product line. Those aspects are not being considered in the scope of this presentation and are already covered in the SEI course material on software product lines. What we will do is we will look at the state of the Zephyr project ecosystem related to each of these core assets. Let's start with the first one, architecture. The cost is it must support variation inherent in the product line. So you just don't have a plan to know architecture. You have an architecture to solve a problem and as it varies, you have the scope of the product line is encompassed in the single architecture. So Zephyr has multiple mechanisms already in place to help support this. You can see that on the left and I'm not going to read through it all. I also noticed from previous experience and from attempting to use this that there's things that are provided by the Hall of Fame project that I worked on that are lacking or seem to be lacking at this point. That's the list on the right. So among these and several of these are worth going through. Giving guidance on when to design to use your own versus a caller's thread stack. That really ends up being a significant question as I've pulled functionality together from multiple repositories back on printers. And when I've had to do the same thing here is what stack is stuff running on? What priority is stuff running on? How do I allocate my resources? And that impacts design. Another one is provide a clean controlled shutdown. And right now Zephyr has none. What I've experienced before is a need to do this in order to be able to close logs out appropriately before a reset, especially before doing a firmware update, being able to have a clean controlled handoff from boot code to application code. There were a few other cases that came up where a clean shutdown was really best practice because it modeled what happens with an object-oriented resources. There's a cleanup that needs to be done. Does everything require a cleanup? No, but you do need to have a mechanism for that. Let's go a little bit farther. Software components. So software product line is composable of components. You'd be able to assemble these things. There's already some examples that Zephyr meets. As you can see, the cost is it must be designed to be general without a loss of performance. Must build in support for the variation points. There's some support for this already in Zephyr. Ords, device tree, driver subsystems libraries, multiple manifest support. There's opportunity beyond this. Adding the directory tree, there's already a directory tree for test applications, ones where you're running a particular test case, where samples are provided that demonstrate how to call on an API without having to deal with all the error handling. What there isn't in the directory tree is a prescribed place to put actual applications, non-test, non-sample applications. And predictability is a very good thing. When we start looking at how does this get used beyond just the particular target environment, we have to set ourselves up to avoid collisions. And so being able to specify and say, everybody should put all of these open source repositories that are going to be aggregated together, should put their application code in this subtree, according to this particular organization and naming pattern, it avoids a lot of conflict. What else? Other things related to how documentation gets designed. Specifying, latent, and it's tolerated for each ISR or thread and preemption level. When you do spine-grained reuse, the person that's developing the reusable components generally doesn't have to worry about how does it give up the processor or the bandwidth of the resources. But as an integrator, pulling all of these things together that have already been designed, I need to know how much I can push around the execution environment and what the design assumptions are without breaking the particular system. Let's go a little bit farther. Test plans, cases, and data must consider variation points and multiple instances of the product line. A lot of this means that the tests need to be parametrized or the test cases need to be parametrized. The results can vary from one product to another, but the algorithm would probably be the same. There is some support for this already. Zephyr already has a Z test library. They've got tests and samples folders. They've got a test runner named Twister. They've already got requirements tags as an extension in the comments using Doxygen. The requirements are coming, needing to, we need to capture better. As an integrator, I need to be able to find how I can hook in whatever else I need for code coverage, MCDC, this may already be there. I need to know what the test plans are for each of the integrated components that I integrate. I need to know what the cases are, the data points that are there because they have to reflect all the variation test points. I also need to know when I integrate this, have I integrated it correctly? It doesn't work. Tools and processes that must be more robust than required for single product development. This is largely supported by Zephyr. It actually needs to get a bit more. One of the things that I discovered was a lot of the concepts are there in Zephyr for supporting these types of things, but they aren't continuously being verified as staying functional yet. For instance, the extension mechanism of module.yaml file that the build system looks for has settings that are inside of it, but I have not noticed in the continuous integration system any tests to make sure that those settings mechanisms are working properly. I expect things have matured some since the last look, but I also expect that there's other issues very similar to that. Let's go a little bit farther. Business case and market analysis. Must address a family of software products, not just one product. Zephyr is actually pretty good at this because they're setting it up for having lots of examples inside of it and lots of samples. There does, they need to take it another level. There's opportunity to update the directory documentation and test cases and samples. And so it's not fully there yet. Project plans must be generic or made extensible to accommodate product variations. Zephyr finds out, the Zephyr build system finds out about repositories and the module instructions in repositories through a couple of environment variables, that tell it where these have been mounted on the tree. This came about before they added any support in for Git sub-modules. And there's actually a lot of benefit in not using Git sub-modules because it means I don't have to change what the parent is when I need to tweak the contents in a sub-module. It actually opens up the opportunity for reusing the parent repository because the link isn't in the repository itself, at least not directly. For high-level support, documentation structure and modularity. Let's go a little bit farther. People, skills, and training must involve training and expertise centered around the assets and procedures associated with the product line. This is in many senses beyond the scope of Zephyr project because the assets are gonna be whatever is needed for the customer identified product line. But Zephyr project is setting up procedures that could be and ideally would be appropriate for product line support. So some of the things that I noticed I would like to see clearly define terms and consistently apply them, terms like code base and module. There's opportunity for clarity there. Consistently following the existing processes. I have noticed some inconsistencies in that. So it will be beneficial for those of us using it if things get a little bit more formalized. Recognize that requirements tracing and documentation generation in general needs to be just as important and extensible as the source code. I'm trying to use the Zephyr documentation structure and pattern and tools for generating all the content I need in my software product line. And I have talked with others that are trying to use it for generating documentation for the customers that have contracted them to do work. This is a really valuable tool if we can bring it up into shape. Let's go a little bit farther. Oops. What's the overall assessment? In my opinion, the Zephyr project is about halfway to where the Hall of Fame winners have already led us. With direction, alignment, and investment, it's possible to match their architectural capability within three years. The Zephyr project will inevitably mature as a software product line because the commitments to adopting and applying software development best practices have launched it in a promising direction. The governance and commitment to security and the audited safety releases are providing framework and infrastructure for a reusable, composable system appropriate for a broad community. And finally, if it doesn't fly, it will fall out of the sky. And for those that are not familiar, the logo for Zephyr is a kite. So what do I think is needed for an SPL best practice? Three things primarily. One is embrace extensibility. How is each aspect of the ecosystem impacted by module extensibility? It has long fingers that go many directions and it's really powerful when it's in place, but it takes a commitment and it takes ongoing maintenance and verification. Embrace live reuse. What does that for ecosystem need to look like when Zephyr repository is not the focus of code and documentation. It's not the manifest repository. What do the submodels need to look like when clients and application repositories have to configure it without having changes injected into it. Third one, embrace composability. What ought to be common so that arbitrary combinations of subsystems and drivers have the requirements met. How do the different elements that can be brought in and out? How do they work together by design to coexist and cooperate or at least not infringe on each other if they're independent? So there's, I think those are the three paradigm changes that need to happen now. I'm sure there's other changes that will be needed on top of that, but that's as best as I could summarize it. Let's go a little bit farther. I've got some proposals that I gave to the Zephyr project on what to do as a next step forward to begin with that paradigm shift. First one, secure firmware imposes requirements on the entire executable. All code built into the image is affected. So the initial proposal, define code base in glossary to be all the source viewable by the Zephyr build system. That's going to change the dialogue and it's going to help clarify what are we talking about? Second, when secure firmware artifacts are needed and they're not needed everywhere, the artifacts also need to cover the entire code base. So the proposal is all tools needed for firmware configuration, build, debugging, testing, and document generation need to, for specific, recognize and operate on the entire code base found through those environment variables that I mentioned earlier. These same concepts we're going to apply no matter whether it's Zephyr or other ecosystems. Let's go a little farther. Zephyr has adopted as a recommendation at this point following many of the MISRA coding guidelines. They're not being strictly compliant at this point. One of them that's really notable because of how much it affects things. I've listed here. It's MISRA directive 3.1, which is required in the states. All code shall be traceable to documented requirements. So generated requirements traceability artifacts will be needed to include the entire code base as part of all. Supporting the star topology was Zephyr, not the hub. Implies that Zephyr documentation tools can generate documentation including requirements traceability from the entire code base. So the proposal is the generated Zephyr documentation are to be adjusted to include documentation found in the entire code base. How documentation is reorganized needs to be managed by the document maintainers and collaborators. Fairly straightforward. Let's go a little farther. Embracing live reuse, not life reuse. Live reuse includes topologies where the Zephyr repository is just another module in the workspace. It happens to be the one that provides the build system. It's the one that provides the kernel, but really everything else could be pulled in from a separate repository. What it means is the proposal is the Zephyr documentation generation tool support workspace level content coming from the manifest repository. The one that is in the hub. And there's a list of things that I've said I've identified is really belonging up at the workspace. There's another set of content that I've identified really belong at the module. But the idea is we're pulling together workspace level documentation and Zephyr's not in the center. Second proposal, the Zephyr continuous integration system verifies support for all user configurable settings in the extension mechanism of module.yaml. Let's go to the last one. Embracing composability. Composability means managing boards, drivers and subsystems so that they can be assembled into a working device without requiring crafting or tuning. The proposal is, and like I said, this is just a start, specify a location in the Zephyr directory tree structure for the configuration overlays that would be used for enabling particular functionality and show how they are referenced in the project's build file. Now, this is not the only proposal or only set of proposals that are necessary for a mature system. These are just the most obvious ones that will start to drive a change in paradigm. Let's go a little bit farther. That's what I presented at the Zephyr Developer Summit. There wasn't the opportunity to engage in discussion and take action on those, but there is opportunity coming up. We're talking about a larger audience here. The previous content, as you can see, is specific to a Zephyr release, happens to be 2.6.0, but most of it is not unique to Zephyr. Much of it applies to embedded software systems in general. So we're now going to look at issues that come up when integrating multiple open-source repositories into a software product line architecture. I ran across these when I was working at HP. I ran across them again when I was pulling open-source projects into Zephyr and having to extend them for the build system. And so I know that what I've run into here so far is not Zephyr unique. Let's see what we found. Continuous integration of multiple open-source projects into an SPO. Let's just review what are the things that have to come together for reuse. And this was pulled from the costs and the definition that are on there. So we must satisfy the specific needs of a particular market segment or mission. We must be designed to be general without a loss of performance. We must build in support for variation points. Must be generic or made extensible to accommodate product variations. Must be more robust than for a single function product. And it must involve training and expertise centered around assets and procedures associated with the product line. And all of this is review. But I wanted a refresher before we moved on again. Documentation needs to include design assumptions and constraints such as latency tolerances and required performances. Keep in mind some integrators of these reused components will put these in a system that behaves differently than the project designers assume. The documentation needs to be entirely editable content because we're reusing it and we're extending it. We have to be able to edit it. Remember, the integrator is not necessarily the last consumer. And it must include the processes and what needed for re-verification of the integrated functionality. We have to know how to verify that it's inside of there. And this may even, let's go farther. Verification needs to have the processes and tests for on and off target verification. Why do we have to verify off on target? Because it's a different tool chain than off target because we're shipping it on target. Why do we want to verify off target? Because generally it's a whole lot faster and cheaper. The number of target systems that are available may be extremely costly and extremely limited. The report, you have to report the results in a format for automated analysis and aggregation. We have to pull together the integrated results just like we have to compose an integrated system.  Now for some of you, these may be new terms, but these actually come from Misra requirements also. Misra C defines unreachable code as code that cannot be executed. Nobody calls it. And it defines dead code as the code that can be executed but has no effect on the functional behavior of the program. These definitions differ what traditional terminology which refers to the first as dead code in the second category is useless code. The Misra requirements neither exists in the code, in the final executable. So there's a lot that has to be provided by the integrators if it's not provided by the open source group, open source maintainers. And given the maintainers are the ones that are fixing bugs and rolling them out, it's just more work on everybody if they don't provide this verification, this level of verification. Let's go a little bit farther. Implementation needs to have client controllable global namespace management. When you're working in an entirely private repository and private code, you have the luxury of knowing that you're owning everything in the entire namespace. Then, and you're responsible for maintaining it. When you start integrating open source content inside of there, suddenly you don't. And when you're combining multiple open source repositories into the same executable, either they need to make sure they don't conflict with each other or we no longer can reuse the code. What it means is the strategy is you can't just use whatever names you want to. You kind of have to carve out your own part of the namespace and stick within it. What else? There needs to be an alignment on level of static analysis coverage. This is becoming critically important with security types of things. There needs to be alignment on the level of automated unit test coverage. And this is needed for verification of integration, verification in a build environment, especially to start bringing in building these things under different tools. Now, one of the consequences is when we're talking about alignment, if you want the code to be able to be reused in a particular target system, you almost always have to meet the demands of that target system. This one's gonna be pretty general. Meet the restrictions for secure coding such as MSRC 2012. And the question is gonna be which rules and advisements and guidance and directives do you follow? The ones that you want, the ones that are chosen by the integrators. It's a hard challenge, but this is what we face when pulling things together. Design needs to, in our particular case with Zephyr, and the design of whatever we're gonna integrate needs to exist under preemptive scheduling. When you get code coming in that assumes cooperative scheduling, we have to redesign. When you get code in there that assumes a private address space and we're now talking about it running in kernel address space, we may need to redesign. These really are inhibitors to reuse. Let's see, what else? It has to use the OS constructs appropriately. Now, in this particular case, some of the things that we have to deal with are when is it a mutex and when is it an in-tlock for providing mutual exclusion that's on there? What is the preemption priority that this is expected to run at? What is involved with polling? Does it expect to hang onto the stack or give it up? Lots of things like that are concerns what we're talking about, especially a resource constrained RTOS environment. What other design issues? Providing configurability and extensibility? Absolutely. Defense in depth, this is a security thing is are we checking, always checking for making sure that the pointer is not null before we dereference it, that the parameter is into a function or valid? Are we handling to make sure that all calls to other functions if they return and have a return value that we're checking the return value and acting on it appropriately? Aligning on error reporting and handling.  Is it, the answer is not always. In some target systems, it may be that you have to keep running code and be able to put the mechanics into a safe state such as when you're controlling a train. Do you fail safe? Do you fail secure? Do you fail gracefully? All of those types of things matter and would require touching the code if they don't fit or using something else. Let's go a little bit farther. Requirements need to be explicit, thorough and a complete set. This really got driven home to me when I recognized that an empty list of formal requirements statements means do only nothing. So if you started with an empty list of formal requirements and said this is what I need the product to beat, a solar powered calculator doesn't meet the requirements because when you touch it or press on it or do anything to it, it can do something. But a rock does or a brick does. And this is also a paradigm shift that we're all having to go through is what are the requirements? How do we capture them? How do we describe them? What are the terminology that we use? Do we all agree with what they are? Requirements will need to be traced to specific higher layer requirements. Why is this in there? Is it dead code? Is it unreachable code? Requirements need to get under track change control. You have to know why these changed. And the list of requirements or the management of the requirements needs to include explicit definitions of the terminology used. Reminds me of a story that probably doesn't matter. But yeah, we have to know exactly what's being talked about here. Especially with open source. Let's go a little farther. So the path forward. How do we engineer the path forward? After some reflection, the statement that came up with two statements that seem to really distill all of this down together. Software product line is the current best practice model that we're trying to achieve with reuse of software in embedded systems, open source or not. Engineering the software is the best practice approach for perpetually meeting the reusability requirements of a software product line. What do we mean by engineering the software? Take a look at the software engineering body of knowledge at the link provided. We were really talking about formal software engineering. It is a process already required for many safety critical systems. Embedded software for internet connected devices is becoming increasingly regulated and will need to be no less rigorously developed in both private and open source environments. It's a mouthful. And I've wrestled with this for a while but this is the conclusion I keep finding myself coming back to. So let's sum up where we've been on this particular thing. We've reviewed what a software product line is, is not and some of the costs incurred in creating and maintaining one. We've evaluated the suitability of the Zephyr project ecosystem as the basis for a software product line for resource constrained secure devices and identified three core paradigm shifts needed for maturity. One of them is embrace extensibility. One of them is embrace reuse and one of them is embrace composability. Beyond Zephyr, we identified key issues that need to be broadly addressed for continuous integration of multiple open source projects into a software product line. Looking back on all that, we've concluded that the best practice process to perpetually meeting the reusability requirements for a software product line is to engineer the software projects for specific target domains. Thank you.