 Today, I want to talk about software engineering for artificial life, in particular software engineering with the goal of getting artificial lifestyle computations to be able to perform useful computations in the real world. This is, well, it's sort of overdue to just sort of have one of these research notebook videos. Also, Robert Golosinski in one of the comments below was saying I shouldn't just be posting these talks that I do at conferences, but I should actually be talking directly to y'all and not freaking out about the time limit so much. So I just want to say, you know, be careful what you wish for, because this is probably going to go on a little bit. And in the middle, it's probably going to nerd out pretty hard for a little while, because I actually want to look at some code. All right, so the plan is first to get a running start sort of previously on, and then talk a little bit about where we are now. And I feel like I really haven't tried to state that as clearly as I sort of think it is in my head, so I want to take another run at that. Talk a little bit about the ULAM-2, the new version of ULAM. We announced ULAM-1, which is called ULAM, at E-Cal, at York in England a year ago and a couple of days, so this is almost the anniversary, and show a few demos, and then in particular show a demo of a fairly substantial example that I just sort of got working in the last few weeks, which is, you know, I think a little bit badass actually. Take a look at that, and then sort of wrap up with, you know, wishing and hoping, okay? So if you're just joining us, the way we do computing today is based on this idea of hardware determinism. You make the physical hardware provide absolute repeatability as good as you possibly can, so that same input, same program, same output guaranteed. And of course, you know, in the real actual world, nothing really works like that. Everything's got a few little errors and rubs and things go off in some weird way, but a computer, digital computer hardware is designed and manufactured to control that, at least as long as it takes to do whatever the computation is. And that's worked really great, but it has also coated us into this bad situation where for the guys who are doing software, they just get to think that reliability is taking care of by magic, and the job of the software guys is to just be as efficient as possible in getting whatever done one wants to get done. The consequences of that is that at the software level, there's essentially no redundancy, no error checking, nothing that you would do if you couldn't rely on an absolute ironclad guarantee from the hardware that everything was going to be deterministic. Exactly the same as expected. The world that we are living in today with all of these crazy security faults and data thefts and breaches and everything getting busted into, that is a symptom. Not so much of the fact that programmers are stupid or that companies ship crap, although both those things might be true in individual cases, but really it's more a symptom of the architecture, the fundamental way that we've architected computers based on this entire hardware determinism efficient software is broken. And it's fun to program in it because you are the utter master of everything that happens. The memory, the RAM is just completely passive. And you say, put a one there, increment that variable, test if this variable is bigger than that variable, and so on. And it does it, yes sir, yes sir, yes sir. And once you start to get a little good at programming, it really is quite a heady feeling, you know, you can make it do exactly what you want. You are the master of the universe, control everything, granted it's a fairly small universe, but it's yours and it's great, but it doesn't scale. It's the dream of dictators everywhere that if I just get everybody everywhere to obey me, exactly everything would be fine and it never is. And these attacks that we're having, these computer bugs and viruses, all of this stuff that's happening is because the whole way we've been set up is this sort of totalitarian government, where not only do the individual data members that are keeping track of everything that's going on, not only do they not have any investment in what's going on, not are they not allowed to care to say, wait a minute, I got changed. They're not allowed to do so. They must be utterly passive. If that was the only way to build computers, well then okay, we would live with it, but there is another alternative. This is what I'm calling living computation and this is where we don't assume hardware determinism. We say the hardware is going to try to do what it says, but it reserves the right to make mistakes sometimes and software is going to have to be organized so that it can tolerate some amount of mistakes and still get useful work done. Now that means the software is no longer going to be able to guarantee to get everything absolutely perfect, but that guarantee was only as good as the hardware guarantee, which was only good up to an asterisk anyway. In exchange for saying that software is going to have to deal with redundancy and taking care of checking its work if it's got a little spare time and so forth, what we get from that is that the job of hardware is to be able to be plugged together as big as we absolutely want to need more hardware, just plug more hardware in and never run into a limit where, well, you know, sorry, we ran out of address space, we got no more addresses, whatever it is, indefinite scalability is the job of hardware to be able to compute as large as we need. And given that we can no longer assume that we are in this totalitarian, everybody will obey absolutely. Instead, we're going to let responsibility flow downwards toward the individual agents by making methods where they can say, well, you know, I don't know the big picture, I don't know really what's going on, but I have enough information to know that we'd better if this thing was over there. So I'm going to move it over there and go, member of the team versus master of the universe. And the difficulty is and so the argument I'm trying to make for eight years now, or in a broader sense for 30 years or more, is that this living computation style where, you know, you don't require everybody to be perfect and you get along and you make things better, is a better way to do manufactured computing than the way that we've been doing it. But getting from A to B, getting from the deterministic attractor to the best first attractor is really hard, because there's zillions of decisions that we made on the process of coming up with the deterministic attractor that all reinforce each other. And if you try to change just one of them, then it looks much worse. You try to change two of them. It looks much worse still. So the idea is we're going to escape from determinism in two or maybe three steps, depending on how you keep score. The goal is using artificial life technology, things where stuff, you know, software programs are reproducing, they're healing, they're growing, they're having kids, the kids are moving out of the house. All of that in service of useful computations, perhaps driving cars one day, no we're close now. But I'm not sure exactly how close the software on the traditional computers are is either. So how can we do it when you have to change sort of everything it wants to leap out of one valley and get into the other, you can do it with a very small strike team that makes an expedition to the other attractor and starts to set up a colony. And that's what we've been doing for the last several years. The steps in building the colony is define an indefinitely scalable architecture, this way of hardware that won't guarantee to absolutely be correct, because correctness is not even going to be well defined, but will do everything necessary so that if you have real estate power money and cooling, you can buy more of these things and plug them together and make a computer as big as you want from here to the horizon. We've done that. The one that we're doing is called the movable feast, movable feast machine, MFM. Create a programming language that isn't counting on global determinism to deal with it. Now, there's lots of languages, the existing languages that one could talk about that might get pulled into this. But we made our own for good reasons, mostly and mostly because we wanted to because again, you adopt an existing thing from the correct and efficient attractor, it starts to suck you back in. We need to reevaluate every damn assumption that goes into programming languages and so forth. So even though Ulam and Ulam 2 looks quite familiar from the surface, we designed it that way to try to make it a little bit less terrifying to imagine, do I want to take a trip to the colonies? It's got some weird features. It's got some fundamentally weird features like unary numbers, for example. You don't find that in many languages. In some ways, it's closer to a hardware description language than to a traditional programming language because in a way, we're lifting a lot more of the tasks that hardware design traditionally would do. We're lifting them up to the software level, making the hardware level just more uniform and indefinitely scalable. Develop simple tools and techniques. That's what we've been doing all along. We've got these demos. You see some of them on the YouTube channel that do various things. We're continuing to make those and we'll look at some in a second. But then the next step is to go beyond just playing with the tiny little things and start building more advanced tooling, more sort of factory stuff to start of settling down to actually bring in some people that are not there just because they want to be explored, but to be there because it's going to be useful for them in some way or at least there's a narrative, a story that's believable enough about how they're going to get to something that's helpful. And to do that, we need software engineering. To do that, we need to be able to go beyond tiny little one atom things that do funny stuff to say, how can we organize complexity to deal with stuff at multiple spatial scales, multiple temporal scales, things running quickly inside, things running more slowly, and so on. And that's what we're starting to do. That's what I want to talk about today. In the future, in the near future, hopefully for step five, we want to build a next generation hardware tile, the indefinitely scalable tile prototypes that will be, you know, absurdly expensive and absurdly weak for what they do. But the goal is for them to collectively allow us to benchmark the average event rate, indefinitely scalable. The primary metric of these things is not MIPS, millions of instructions per second, but how many events can you deliver to each spot in the matrix that you're working on in a given second, assuming that some of those things are going to have to talk to neighboring tiles, so there'll be communication coordination involved, taking all that into consideration, what air can you show us, what average event rate, events per site per second on average. I will be thrilled if our next generation hardware can show 10 air. I mean, I'll be satisfied if it can show one air because we're drawing a line in the sand. I'm not a hardware guy, I need hardware help. The point is, is to draw a line in the sand and say, you know, hey, it's starting to look like this architecture could actually be useful for something. I bet these computer engineer guys, especially because now they're liberated from absolute determinism, could just crush this. They could be reaching 10 air, 100 air, who knows. And then with that prototype hardware, less and less prototype, more and more useful as time goes by, hopefully we start to actually be able to do system control demos, take a bunch of these guys and have them become the sort of skin and brain simultaneously of a little robot, that kind of thing. That's down the road. Okay, so today, more about step four. Oh, and then, you know, step seven, you know, like Lena says, you know, world domination or as I would say, you know, for the benefit of society. All right, so, ULAM-2 announced July 30th, announced today, at least I'm recording it on July 30th. We'll see when we get through posts and so forth. So it's ULAM-2, there's been a bunch of little releases just trying to get the packaging working and MFM-334 might end up being 335. The easiest way by far is to use the personal package archive and install it on ULAM-2. Any of the current long-term support 1204-1404-1604 on an Intel box, 32-bit or 64-bit. The more machine you've got, the better. If you've got an eight core burner, well that would be great. But it'll even run, like, is this thing running? There we go. So, right, can you see this? This is my little ancient EPC, I think it's the first generation, 701 or whatever the heck it is. It's running the burn demo, which is one of the demos, which is included in the ULAM package, which you get if you install now. And, you know, it's running like crap, but it is running. The simulator will take advantage of as many cores as you've got, but it'll fall all the way back and things will just get slower and slower and slower. And so let's look at that demo actually. One of the programs that gets installed is MFZ Run. MFZ is the packaging format, like a jar or a zip. In fact, it's based on zip that you can put together with ULAM code, compiled code, and initial kernel configurations that you want to do. If you just type MFZ Run, you get a bunch of help, and at the very end, you get the list of the demos that are included. It sticks user bin on, it doesn't really need to. Here's the burn demo that we just looked at on the EPC. It works here too. I was going to show you another one. Let's look at the base layer. Is it kind of a cap in it? Yeah, it does. All right, so this one, look at this. We got a bunch of these touch reporter guys sort of in the middle, and they are sensitive to mouse input, and this is just a tiny little down payment on how the Moogle Feast grid is two-dimensional, but it has the potential to interact in the third dimension through the base layer, and there's a library site utils in that you can write code. So this thing is detecting mouse motion, it can detect dragging, it can detect clicking, although you notice clicking is not necessarily hitting one exact site. It's more like imagining sort of a tablet with a finger, but also the point is we need to come up with things that will figure out how to debounce that kind of information ourselves rather than just assuming we're going magically be able to hit the one pixel, the one site that we want to do. Also in this directory is the site writer demo. There's a video of that on the channel where, you know, has it started to show up yet? It's starting to there, where, you know, it gets colors scribbled all over the screen, and even though there's only two atoms there, colors get scribbled everywhere, and how is that possible? Well, the way it's possible is because the colors are actually being painted onto the base layer, so the atom can move on and leave an effect in the world. This could be used for pheromone trails, if one's doing an ant model, or a limited sort of communication, or a little bit of extra state that's accessible from the site that you're in. And the reason we can see it is because in the full-on version of the simulator, this is where you get the interface. If you dare, you click on more, you get the whole thing. Back is what are we going to display in each little rectangle for the site. Middle is what we display in a circle inside that, and front is what we display in a little teeny dot in the center so we can pick whatever we want for all those three layers. In this case, we're picking the site paint to see what the site writer atoms are doing. Now, again, with all of these demos, it's really just the simulator running from a particular initial configuration, so if we want to mess with it, we can do that. We can add a bunch more site writers and see what happens. We can take site writers and add a bunch of touch reporters and so on and so forth. So, I told you this is going to go on a while. So we've got all of these demos, and they're great, and they serve in addition to being just sort of fun to play with and fun to look at, what they're doing is they're training our eyes for the kinds of dynamics that happen naturally in these sort of systems. I mean, a lot of these demos you can find in like NetLogo, other packages meant for agent-based modeling, and so forth. It's all very similar concepts, and they're worth looking at just to see, I mean, like in the burn demo in particular, in a classic burn thing, you know, you can get a loop set and it'll just burn around and around and around forever, which is sort of weird to think about burning, but it's as if you're imagining you have a circular forest, and the forest is burning, and it takes so long to get around the circular forest that the forest has regrown, and it's burnable again once the time it gets back, and you can get these ring oscillators going. And it's a model of things like transmission of signals in neurons in your brain. It's related to how your heart works, the cardiac muscle pacing, and so on. All of those things are good to teach us what the sort of, you know, basic resources of our colony are like, but once we've played with a bunch of them, we need to start saying, okay, well, how can we build larger tools with them, and that's where software engineering comes in, and that's where several of the new features of ULAM-2 come in. So ULAM-1, where things have been carried forward, it's just a regular looking programming language. I mean, if we look for the sake of argument, if we look at, let's look at site writer, when we install the package, everything ends up in user-lib ULAM. Let's see in the ULAM side, share ULAM demos. So there's our demos. The site writer is in the base layer, like that. So here's the whole thing. We have a data member, which is of type argb, which is a four element array where each element is an unsigned eight. So eight bits, an array of four groups of eight bits, 32 bits total. The behave method is called automatically by the engine when an element, an atom of type site writer, it gets a turn to have an event, and it just pulls up its color, modifies it by a random number, and writes it back. Now you might think, ooh, what's going to happen around when we have wrap around there? What if I add minus two and the color is only one? It's going to wrap around a 255 and the color is going to completely change. Well, no. One of the unusual features in ULAM is that arithmetic is saturating. So one minus two is zero if it's an unsigned, which it is in this case. Although we can't really tell that, we'd have to go look in the site utils, which is one of the standard library packages, in order to find out what the type of channel is. But as it happens, it's unsigned. So we modify the color pinning at black and white, if need be, and then we use the site utils package to paint it on the floor, and then finally we swap ourselves with state one is the guide of the west site one. We are site zero, site one is the guide of our west. So that would mean sort of go west, except for the fact that we have, whereas there it is, we have some metadata declaring that this thing is symmetric, it's rotationally and mirror symmetric, which in the case of the movable feast means every time this guy's at an event, pick amongst its legal symmetries at random and apply it. So in this case, white west might actually be north or what have you. Okay, so ULAM, ULAM one, from one point of view, it's a very conventional looking language. It's got objects, it's got methods, it's got data members. There are weird data members. Primitives and objects are allocated by the bit, arithmetic saturates, and then the biggest pain of all, which is the whole point, is that there are no pointers and there's no random access memory. There's just a tiny number of your neighboring sites. We looked at zero, which is where I'm stored. We looked at one, which is one site away, depending on the symmetry and so forth. And so fundamentally ULAM is a method of programming transition rules, like for a cellular automata, like the game of life, except for relative to standard cellular automata, a much bigger set of neighborhoods and much more particular symbols per state for each one. But unlike traditional programming languages, you can't take a pointer to anything. There is a stack and you can have functions that call functions that call functions and return and the stack is assumed to be ample to do serious programming. You can have local variables in stack frames, methods that have been called, but you can't take pointers to them. You can't store them any place. The only persistent memory you have available to you is your event window, that little neighborhood, plus the base layer underneath you, the site paint, and so on. In ULAM too, we add single inheritance like Java and virtual functions like Java and C++, and we even add reference variables, but they're limited. You can't have a data member that's type reference because it doesn't actually really make sense. All of the persistent memories out in the event window, those things do not have addresses, so you can't actually take a reference to them. When you're executing on the stack and you're doing locals inside a function, you can because all of that stuff is going to disappear as soon as the event is done. The stack unwinds, the event is done, some other guy gets called on. His behave function and off he goes. One of the most aggravating things, which again is fundamental to the mission, is that all objects in ULAM1 are the same size. Well, they're all fitting inside an atom, which is 96 bits, minus a bunch that are used for type information and error checking, so ULAM programmer only actually get to use 71 bits for an object. That's still true for anything that's going to be persistent, but I have a notion of a transient, which is a struct that acts just like a class pretty much. You can have transients inheriting from transients and so forth. That can be much larger. They can be a kilobyte in size if you want. Eventually there'll be a limit on stack memory, but it's again imagined to be reasonably ample to do software engineering with. You can have them and the keyword is transient to drive home the fact that they only exist from one entry to a behave function until the time that behave function leaves, and you only get to do that for one event. Still no pointers, still no RAM. Okay, so we looked at these little guys. We looked at some of the little demos, but I want to talk about a bigger one, sort of a more of an example of software engineering that I really just got going, which is cell 1.0. Now, you know, it's anything but a real sort of biological cell, so that name should be, you know, taken with salt lick. But the mission of this exercise was to build something, some mechanism that could replicate a relatively large object where relatively large object means dozens or hundreds of sites maybe, but not necessarily thousands or millions. Since everything is small, we have to size things as we go. But we want to be able to say, okay, here's a pattern, and you go wham, and something happens, and it takes some time, and then we've got two of them, and they're pretty much the same. With best effort results, they are the same. Something might go wrong, but assuming nothing does go wrong, there'll be copies. In order to do this, there's, you know, even though we are programming, we're just programming these individual little transitions one at a time, and they have to compose together by noticing, oh, in my event window, look, I've got some blocks here that they're content. They're the kind of thing that I want to move. Oh, there's a thing I don't care about. I'm going to ignore that and so on. I have to code all that up. Given that events happen asynchronously, there's no absolute addressing. We cannot say that, well, just give me the contents of location 2634, because there is no 2634. I'm at zero. I'm the center of my event. If I move and get another event, I still think I'm zero, even though it's different than the zero I had on the previous event. When we're starting to talk about objects, we're meaning now collections of atoms, like a molecule or cell. And when you start dealing with this, when you actually start programming it, you have very, very basic stuff. Like, how do you tell whether an atom is considered part of the object or not? And worse, when you're starting to replicate, how do you tell whether this particular atom is part of the parent or part of the kid? You need to tell it apart because different things happen to them once the kid separates from the parent. So that's the problem of distributed control. One of the first things we had to deal with is how do you die cleanly? I mean, when you look at a movie, like Tron or Matrix or whatever it is, and somebody gets killed inside the digital world, they fall into these bits and then the bits vanish, which is very convenient from a point of cinema instead of having one pile of half-cooked bits over here and another pile of half-cooked bits over here, like you'd have when someone got chopped with a sword in real life. But how the heck is that supposed to happen? I mean, though all of the things representing that thing, they're distributed in space. They're made of zillions of things that are operating independently. Object identity, clean living, clean dying, basic, basic stuff that comes up in this code. Distributed control, and then finally the software engineering, if readable code that there's hope for, it could be reused either literally or with modifications for other purposes. And again, in traditional cellular automata stuff, that really just doesn't come up. Because the entire control system is imagined, number one, to be really part of the physics rather than in this programmable layer. And all of the work is in the layout of the pieces in the grid. But now we're taking a lot of that down. It's on the same idea that you could build a computer, and this is as Peter Corey mentioned in the comments recently. I think some Corey, saying you could take the movable feast and you could implement the NAND gate out of it, and then you could have it build up a traditional von Neumann machine on top of it. So isn't that kind of weird? And that's absolutely true. But we don't make computers, we don't make actual normal computers today out of NAND gates. You know, we make them out of more complex things because it's more useful. And here, we're going to do the same thing rather than saying the goal is to find the minimum set, you know, two symbols, neighborhood of four, and so forth, that can lead to a certain behavior here. We're deliberately giving ourselves more room to engineer. And that does not make everything sort of magically easy, because we still have the fact that it's asynchronous, the object is bigger than the neighborhood, we have to schedule all this, we have to coordinate all this without determinism or synchronous updates. Okay. So how are we going to solve these challenges? We're going to tell who's in and who's out by having a tag. And if you have the same tag as me, then we are in the same object. You have a different tag, you're not. We're going to put that tag up in a base class, which is actually going to be a template base class. So we can say how many bits we want to dedicate to the tag in this demo, we have five bit tags. And that's going to determine how we're going to kill things and so forth. And well, actually, let's look, let's look, we'll come back to that in a minute. Oh, man, it was like a half an hour already. It's going to go forever. All right. So here's the way that the solution builds up. Suppose we take one of these guys. This is, we plop it down, and it's a little, I think 16 side line, and it heads east. We can make a bunch of them. And when they run out of the edge of the universe, they go away. And I developed these things called swap lines to do a little demo in a paper that's going to be coming out in the artificial life journal real soon now. And it took me the longest time to realize this. So what these lines, what these guys do is they wait and make sure none of their neighbors are behind them. The neighbors are all caught up. And then they swap themselves forward once. And so that way, even though the line isn't completely straight, it never gets more than 45 degrees, it never actually tears. Okay, because everybody at the front waits until the back man catches up. All right. It took me the longest time to realize, let's make something here, that, okay, here's the thing, that if these swap lines are swapping to the east, that means anything that they run into is actually moving to the west. Like that. And this idea means that, you know, perhaps we could use swap lines to come up for a method of large, where this is large now, bigger than an event window, and actually see the event windows if we want there. Let's get a line going. Yeah, so those, the, I don't know if you can see it, the little diamond guys here, that's the size of a single event window. And it's flashing around because the events are happening at those various places and so on. Like that. So we can get a bit of a, we could use the swap lines to move large objects incrementally, and how to move a large object in a cellular automata has been a bit of a challenge for quite some time. And that's why, you know, in Conway's Game of Life, the glider, this tiny little configuration that moves is so celebrated, and then the larger spaceships and tractors and various things that they have that move while retaining their pattern are all sort of inherently interesting. One problem with, again, the sort of deterministic everything out in the world, nothing, this minimal amount in the rule set is that those things are extremely limited about what they can do. You cannot make a modified glider that has six guys in it and, or carries a different kind of configuration. All of its shape is used for the dynamics of moving and repeating in its pattern. Whereas here, in principle, you know, we can change the shape. We could change the shape. We could add other stuff to it. And if we could figure out a way to release a bunch of swap lines in front of it in some coordinated way, we could move the whole thing. Okay? So the problem of large object motion, and a lot of people have taken cracks at this over the years, you know, this would be one way to approach it. And the thing that, again, as you sort of think about the design stuff, the reason a swap line is helpful for this is because it's not completely synchronous, because the world is not completely synchronous, and the world can't be completely synchronous if it's going to be indefinitely scalable. But it's a little bit synchronized. Things wait for the back man to catch up, so that as long as the line hasn't actually gotten torn or damaged in some way, we can make certain assumptions about it that if they're, if they're not at the end of the line, then we're going to see a guy before me, next to me, or in front of me. And those are the only three possibilities. So I can tell what's going on locally. So a swap line is an example of a little bit of synchronization. And what we're trying to do is rather than assume we could have the architecture take care of synchronization for us and always do, you know, kachunk, kachunk, kachunk, kachunk, the idea is to use just the amount of synchronization that we need to get the job that we're trying to do done. And by keeping that limited stuff, we leave ourselves open to be able to apply it to different shapes and different circumstances with different inputs in effect. We get more general, more flexible mechanisms if we limit the amount of synchronization that we need to just when we need it. Okay. So I took this idea of the swap line. And once we have this, well, you know, so now we've got a guy who's moving, why couldn't we like as though we're moving him, why couldn't we like make a copy of his last line and leave it behind him? And then the next time he moves makes a copy of his next to last line, and leave that there as well, and sort of make an on the wing replicator. And that's what I did. So here's an example. These are blocks. And blocks have a tag, a content tag. This guy is hex 17. Again, we have five bit tags available like that. Now by itself, a block doesn't do anything. But let's pick, let's see, let's go east. Let's plop one of these sea plates in here. And I blew it again. That interface could use some work. So a lot is happening here already. When we put down one of these things, what happens is it circumferential, circumferences, it plates the whole object all around out to a depth of two. It's this particular atom is called sea plate, because that's what it does. It does circumferential plating. And it's got a ton of stuff in it. Whoops, a ton of stuff in it. Whoops, and I'm putting that pull that in. That we're not going to really look at here. But among the many purposes that sea plate serves is it isolates the object that's going to be copied. It is used to establish a absolute addressing grid from the lower left most point that is in the bounding box of the object to the upper right point of the bounding box of the object. And then each of the sea plates within the entire collective localizes themselves relative to that grid. And that's what's actually happening now. And then once the grid has actually stabilized, we move on to phase two, which is the actual copying step that uses like the swap lines, except now the swap lines are like tractors and each of them has a trailer going on behind. So it's moving two steps at once. And when it gets to the column, its job to copy, it replaces the trailer with a modification of the thing that it's copying. And then when it gets to the back, it dumps it off. So let's just let this finish for now and see if it's pretty cool. Replication. It's cool. We can send guys in different directions. Oh, and once again, come on. North. Send this guy north. Send this guy south. And so on. Oh no, actually look at, see now that guy's kind of messing up. Because he's getting interference right in here. He hasn't managed to successfully finish the plating because he's running into interference from the kid that the other one is making. But actually in this particular case, it looked like the kid got out of the way and now this guy is just behind and hopefully he will successfully localize and maybe move on to actually making a copy. He may not, there are any number of ways that the replication can fail. In fact, we can induce one deliberately if we want. And again, what happened there? All of the sea plate, all of the stuff associated with the replication disappeared but the object was left behind. There are other, we can get into worse situations where in fact the thing will kill the object entirely. I'll give it another shot. But in that case, it was a miscarriage but otherwise it worked okay. So what this is, it's kind of like, you know, it's like, well it's like a 3D printer, right? Working layer by layer. Except it's only in 2D making 1D layers so it's kind of a 2D printer. Like that. Which is only one sort of limited but very effective approach to replication. The, one of the goals of the original replication stuff going all the way back to von Neumann cellular automata was to explore this duality between like DNA. They didn't know what DNA was at the time. But to explore the duality between components of physical systems being interpreted as control, execution, things to do, and being then just taken as absolutely passive data. And in this case we're doing reproduction in essence by self-inspection. And we're actually, you know, since we're able to spread ourselves out as we pass swap lines through, we can inspect a given line and say, okay well I need another guy like that, oh did I send that guy out of the east? All right, so there's another one that's sort of messed up. Now it turns out this will eventually clean up after itself but it'll take a very long time because that's our absolute last backstop. In addition to the being able to abort a replication, we also have poison that, so we really wanted to send a guy west. So why don't we send this guy west and maybe he'll run into that poison and he'll have a sad outcome. This is a lot of fun to play with. This is not, oh say there we go. This is not yet in one of the demos. This is brand new. But how does this actually work? We could talk about software engineering. Let's talk about software engineering. The circumferential plate, the C plate has a bunch of jobs. These are some of the data members. This is, you know, little UML. Now with 71 bits, so we've got S2D. S2D is a data type that is an array of two seven-bit numbers like that. So an S2D takes up 14 bits all by itself, which is a lot in ULAM land. I mean once you start figuring out this stuff it's kind of like sort of like bonsai programming. You know, you're making these little teeny things where, you know, one bit here is all you need. Oh, that's really three bits. Couldn't I do it with two bits? Which is, it's fun. It's got a sort of purity and cleanliness, sort of like assembly language in some ways. But the size of an S2D being seven bits, that determines our sort of build plate in, you know, 3D printer land. So we can build, we have a chance at replicating things up to 128 by 128, more or less. It doesn't mean that's all very likely to succeed in any case, but that's our capability. We have a source, which is really quite nice. Can't take the time to talk about it now. But every time a C plate, which just automatically spreads around the object, every time a C plate creates an offspring, it sets the source of the offspring to point back to it. So in fact, when we got done, and we had, where is it here, you know, if we take one of these guys, I'm just going to start them up a little bit and then stop them. He's not running. All right, so here's the C plate, like this guy, oops, I did it again. His source is 15. We have to look in the thing and find out which site number that is. You really want to have the event window picture. I guess I don't have it here. Can you see it here? Oh, yeah. I was trying to figure out how to get the volume to be right. If you go to robust.ucs.unm.edu here. So site 15 is up one and two to the left from me, and that's the guy who created me like that. And so if we do this, if we track the source here, that the source actually creates is a parent pointer in the offspring tree. And so this entire C plate collective around this whole thing, in fact, is also a NRE tree, a general tree, that you can trace from the last guy who was born through his parent all the way back to the root wherever it was. I started this guy. Did I start it? Yeah, I started it there, and we can tell because he's the only guy who has a source of zero, which is himself. And the algorithms take advantage of the fact that the C plate has two addressing mechanisms. It has X, Y coordinates. I am located at 4, 4. The guy below me is located at 4, 5, and so forth. But also it takes care, takes advantage of the tree structure in order to sort of break ties and bias the gossiping algorithms that work. It's a little detailed, but it's very nice on the one hand. And it's also familiar computer science. These are trees. Unlike typical trees where we try to make them as bushy as possible, these are very long straggly trees, but they have uses nonetheless. And we are representing an NRE tree in 4 bits. And how can we do that? We can do that because we know that our parent is in the same event window as us. With 4 bits, we have enough in the way that the C plate uses it to find all of those possible locations for our parent. And if the parent needs to go the other way, if the parent needs to go down to the kid, it can just search that location in its neighborhood and look for guys who are pointing back at it. So we can navigate in both directions in this tree. Again, only one small number of steps in a given event. But over time, we can pass information up the tree to the root. We can broadcast information from the root out to the leaves and so on. C plate is not a standalone class. It inherits from U-grid content, which is in charge of forming the absolute localization, finding the zero coin and so forth. And C to D is, these are 16-bit 2D coordinates, so each C to D takes 32 bits, which we really do not want to blow 32 bits, especially because we have two coordinates down here. That would be 64 bits right there just to remember where I am and how big the space is. So that's why we use the little squished down one and accept a smaller build plate in order to have room to do other things with our bits. So U-grid content provides mapping operations. It's not either U-grid content inherits from rotate content, content which has a 2-bit data member that specifies a rotation relative to east is east and north is north. So the reason that we have an east C plate and a west C plate and so forth is because those trigger C plates with a different orientation. So when we make a guy who's heading south, the code is all written as if he's heading west, I think, and then the rotation is being implied transparently by rotate content. And rotate content in turn inherits, whoops, inherits from content, and content inherits from this thing called QID, and that's where we actually start. And QID is a Q stands for quark. Anything that's smaller than an atom, well, anything that an element is going to inherit from is a quark. So QID is a quark, so is content, so is rotate content, U-grid content, and so forth. They're kind of like abstract classes. They're sort of, you know, they can have data members, but they're sort of incomplete until they've finally been instantiated as an element, and from elements we can make instances that are called objects. QID is a template because you can provide information to say, you know, everybody has to have the given species ID, and that ends up costing nothing because it gets compiled into the code and represented by the type of the atoms, rather than by the small number of data members. The number of tag bits we set to five, the number of progress bits, the other thing that IDs provide, QID provides, is a timeout watchdog, and there it is, yeah. It provides a progress method, so the code down below needs to call progress every so often, or eventually the watchdog will not only destroy the guy who failed to show a watchdog, but in calling it this emergency death method, here we have, we've got the sample. So this is what the behave method looks like at the level of QID. It calls super dot behave, which in this case there isn't any super, so it inherits from herself, the sort of analog to object in Java, and then all it does is count the watchdog, increment the watchdog, and if it reaches the alarm level, it calls emergency death, which erases itself, but first it looks everywhere in the neighborhood and signals emergency death on everything else, and that's in fact how the poison works and the replication terminator works. The poison actually signals emergency death. The replication terminator is handled lower down, and that's why it can actually leave the parent, at least in some cases. So this is a lot of stuff, so even squishing the data members, the coordinates down to 14 bits is not enough for all the things that we need to do, so in fact C plate has here, so this thing U, which is not labeled with M, so it's not really good, programming practice, we're not being systematic about our data members, is a union. So here we go. So there are three phases in the whole process. Grow is surround, build the C plate out and perform localization. Grow is when we actually do the copying line by line, and then QID is at the end when we're done and we're going to separate it and strip out, dissolve away the C plating, and each of those, being a union, gets to have different use of the same bits like that, and the reason I wanted to bring this all up is that the copying mechanism has to do some pretty tricky synchronization, and so here, for example, we've got, okay, let's get rid of this guy, we've got this green guy and this red guy, and those are really C plate, of course I just got rid of it, now I want it back, they are C plate, these are all C plates and so forth, but what makes this thing special is he's the leftmost highest C plate that exists, and this guy is the rightmost southernmost C plate that exists, and so this guy becomes the, in charge of, there, so this guy is in charge of issuing the swap lines to be copied, he is the head commander, this guy at the back is the tail commander, he's in charge of allowing the lines to release into the kit, and if you look, it's a little hard to see in this one, that the line actually squares up, it can get kind of wiggly as it goes through, but once it gets to the tail commander, everybody dresses the line so that we know everybody is ready to move into the next phase and everybody waits until the tail commander releases them, and in order for this, I mean there might be other ways to write this, but you know this is the way I was managing to get it to work, and all right there it is, just for every single time, it's like Sancho Bob and the Rakes, so now the head commander and tail commander are different axes because the thing's heading down and so on, but the head commander does not release the next swap line until the tail commander reports that it's gone through, and how do they do that? Well if you look at the little dots of color inside the sea plates here, they're shifting between red and green and blue, and actually what they're doing is they're sort of playing a little game of rock, paper, scissors with each other, rock is red, paper is green and scissors is blue, and the only one who's allowed to change to scissors is the head commander, the only one who's allowed to change to rock is the tail commander, and the only one who's allowed to change to paper is the root, the original guy where this all standard all started, and they work together to coordinate between it, and again this is another example of, where's my UML, this is another example of how we use a limited amount of synchronization just what we need in order to do it in order to get coordinated action done at a distance like that, so we have a rock, paper, scissors class whose job is that, and that costs us two bits, and in fact we represent it as a unary two bit number because we only need three states, zero, one, and two, and that's all that you can represent with two bits expressed in base one, all right, running out of time, way running out of time here, so this is a non-trivial from some points of view, certainly from compared to the burn demo and the fork bombs and so on, this is a non-trivial amount of code, that UML diagram was not complete, that was just some samples of the classes, didn't actually have the behavior classes that were involved, there's a separate class for controlling when we're doing grow and copy and kid, although the kid's very short, but it's a way to be a flexible object replicator that works with pretty high reliability as long as it isn't impacted by events happening around in the world, and to some degree it even handles unexpected events either by miscarrying or in the worst case by actually cleanly killing the object that was trying to replicate, all right, looking forward, language development continues, there's much more that we could want in the language, I really want to get the motion, I mean so this in a way kind of a little bit out of order because this sort of took the motion technology and is applying it to replication, it'll be nice if these guys could just move themselves around without it, cells control their own motion and replication, and we really want to start looking forward towards tiles, making a new prototype tiles, we're probably going to use one of these little tiny system on modules that'll run Linux so that the port of the code that's currently running in the simulator to the tile won't be that hard, the tiles will be incredibly expensive compared to what they could be if they were optimized for it, but again they can serve as a line in the sand, and that's about it, and let's do one last one or maybe we can just sort of leave this running, and it's worth noting that we can actually reproduce things other than just block content as long as they're sort of surrounded by block content so that when the circumferential plating comes through it'll know what is supposed to count as inside and outside, so why don't we send this guy north here, see if that works, bigger objects take a lot longer to localize, and there's just in general more, it's a higher risk replication, actually this guy is going to be heading, this dark area here is in between two tiles where there's significant timeshare, you know, tidal effects due to the communication delays between the things, which also can stress the mechanisms, as much as possible I tried to make the mechanisms interlock so that if something isn't ready because for example time is running slower where it is, other guys will wait, but there are still in particular the ending of the growth phase, determining when we have localized and we're not going to see any more in the coordinates of involves a certain amount of ballistics and timing and there can be failures, we're probably in pretty good shape here because now we're into the copy phase and that's a little bit more robust. Is this the be all end all of object replication? Absolutely not, it's kind of brute force, I mean it would be nice to have the thing grow from the inside from the seed, hold it from the approach, it would be nice if it could handle things that, you know, sort of more, you know, sloppy way rather than this, you know, literal line at a time and one of the other things that C plate does I didn't get to talk about is it does passivization, that all the, everything that was inheriting from content, the blue blocks in this case, when they see C plate around they suppress their normal activity, I mean because these things are all happening in parallel, those res that I stuck inside the O there, they would be trying to move if they could because they don't inherit from content, they don't know what's going on, now in this case they were in an area that was small enough that C plate got in there and kind of immobilized them all sort of like in gel, but in a more general case if you make a larger object with this thing with big gaps, you can have all kinds of difficulties because things will be moving around and doing their normal whatever they do while the swap lines are moving through and trying to copy them and in fact it's easy to end up with not quite exact duplicates and you know there's an awful lot of development that has to be done between here and there but it's possible that we could end up seeing evolution happening not because it was programmed in deliberately like we do with typical genetic algorithms and a-life software models but just because that's what happens because of our best effort implementation of replication motion and so forth in this world of best effort computing, I think those in fact aren't quite they might be seven res each, not sure that's it for now Robert I hope this was long enough for you thanks for watching