 Okay. Hi. I'm Lionel and I'm going to talk about tree matching with behavioral trees. So the aim of this presentation is to explain how to organize sub-trees into complex and deep trees of data. It is related to Python, but you could use these techniques in any language that support reflexivity. So we are going to speak about behavioral trees and to define it. And so after that, I will try to explain why we need tree matching and in the common use case for using tree matching. And during all the presentation, I put some code to explain how to do all this stuff. So what is a behavioral tree? A behavioral tree, in fact, is basically a diagram or schema that represents a process that describes different tasks that are useful and very used in video games. For example, to describe the artificial intelligence of a boat, or the behavior of the boat. For example, here I could explain a boat in the game that crossed the door. So I begin to describe with our symbol a sequence of tasks to be executed. So I begin to say to my boat, begin to work to the door. Behind this task could be used a pathfinder algorithm to find where the door is, for example. After that, do a complex sub-trees that is described, that begins by a question mark. A question mark is another abstraction provided by behavioral tree. And the arrow symbol means sequences. But the question mark, in fact, is called selector. A selector on behavioral tree is a list of tasks. But we try each one. And the first that will be OK is all the sub-trees is OK. So I will try to open the door, but this task could be failed. This task could be failed because I need a key to open the door. So I will continue and go to another sequences that will try to unlock the door and finally open it. But it could be, in the task, unlock the door. I will check that I have the correct key for the door. But it could be, I did not get the correct key. So all this stuff could be failed. So finally, I could just smash the door. And after all these possibilities, possibly tasks, I will work through the door. So from this diagram, I describe a complex process with a lot of steps. The three main components that I use is the task. This is a simple abstraction to say, OK, do something. This is very easy to understand in programming language because it's just a method name. But behind this task, you will check your context of the environment of your video game, basically, to know if the task is doable or any context you want to test. After that, I have the sequence, so the arrow symbol, that it just do the next task if the previous task succeeds. And the selector, this is in fact like the or, the boolean or, because in fact it is do the next if the previous task fails. So in the selector, I don't do the task. I don't do all the tasks because I just do only tasks that say OK or fail. And I stopped to do the task if at the first succeeded task. OK. This is, I show you the representation of the behavior tree as a diagram. Now I will explain behavior tree as a piece of code. The main part of the behavior tree, we will describe the task. So I create a class task. And at each step of my process, I will call a method that's named a tick. A tick is related to time in the video game, but in our application or problem here, tree matching, the tick will be something else. But the important things that this method tick do something and return the status, the status of the task done. But the status is not just a boolean function, fail or success, it's a special enum with failure, success and running. So the first part is a task could say OK, I didn't finish, so just say running. So you need to test me again in the next tick. So after define the classical blocks, the task, I will create nodes and also define the nodes and the roots of my tree. So I need to create tree and each node and the roots of tree is related to child. So when you recreate a tick method for a tree element or task, I will be related to my parents and to my child. Because with this block, I could be inside the tree and the task block, it's a leaf, so I do not rely to anybody. With this, I could define my famous arrow symbol, so the sequence. So the sequence, the tick method in the sequence could take user data and return the status, but in fact is related to child. So for each child, I just call tick on the child with the context, don't use our data, and get this status. And I will handle this status as a task. So if my status is running, I'm also running. So recursively, from the leaf that say running, all my better tick could say, okay, I didn't decide what I've done. If I fail, I stop and all the sequences fail. And if I could check all my child, the sequence is a success. So it returns success. After the sequence, we have selectors. So the selector is like all. So in fact, we try old child, we check the status, like the sequence, if the sub-task is running, I'm also say running. But if sub-task success, I stop and say success. And if all my child fail, I fail too. With all that, we have just three basic blocks, but we could imagine another blocks. So if I understand the concept of any part of my better tree could say fail, success, or running, I could create, for example, a concurrent block, a concurrent block that will propose to test each child concurrently. So I could, in the new position of selector, just run a test and call tick on each child in order. But here, I will call tick in each, in any child. So I will enumerate my child, store in a statu-list all status of all my child when. And if all my child when has finished, I did not have a task still running. All my child could be fail or failure, but never running. I could check, I need only one success to say I'm successful. If I didn't have only one success, I fail. My concurrent test, my concurrent block say fail. And if I have still a running task inside my child, I'm still running. So with this kind of abstraction, I could, in a synchronous way, manage asynchronous processes, notably with the concurrent abstraction. So this is the presentation for the concept of behavioral trees. And now, how to use it? In a precise use case, that is tree matching. Tree matching, in fact, it comes at any moment where you need to do some data validation. You have a complex data representation inside your application, and you need to identify inside this big data tree some form and validate that is correct or incorrect. You could use tree matching when you want to do some data transformation because you want to match some form and rewrite inside your tree only this kind of data. And more generally, you always need tree matching when you want to do some data generation because you have a first data tree that you will traverse, identify some things and call some other method that creates another type of data. So you will have the first data tree that generates a second data tree. And in fact, all these use cases are in fact inside a compiler. When you want to identify some pattern in your bigger data tree, this is a semantic check because the meaning of what you write in your language represented into an IST, in fact, is good tree construction. All IST transformations could be done with tree matching and at the end, code generation is basically tree matching. All this stuff, in fact, are already done with functional language like ASCEL or another language that supports pattern matching. Pattern matching is a statement, a powerful statement in this kind of language because you could easily match a tree and a partially sub tree. To basically do a tree-on-link, you begin to write a recursive function that traverses all your tree in a top-down way and use a pattern matching to identify nodes, deconstruct it and do something with it and call some piece of code. This could be useful for a major part of your stuff, but when you want to do some tree reconstruction, to identify some part of data and rewrite it, you are not in a good way. You can't match in a top-down way because you begin to match roots before leaf, so you can't rewrite leaf. This is finished. If you want to do some tree reconstruction, you need to match and identify your tree in a bottom-up way. If you have more complex pattern matching that are deepest from only one level because you want to match an ancestor and a child deep at two or three levels because you want to check a special construction inside a statement for a language and other stuff like that, basically pattern matching is not enough. For all this kind of stuff, I think about behaviour trees and I have an intuition to test that behaviour tree is a certain way to do a finite state machine. But in academic definition, a behaviour tree is like a Yara-Marshi-Kol state machine. This is a kind of automata more adaptable and more versatile to the basic finite state machine. You don't have an explosion of states. You have a lot of good properties. So I try to use this kind of new way to describe a tomato behaviour tree to identify and to do tree matching. My main idea is to have a work method that allows us to traverse our data tree in the correct order, so bottom-up, and to notify our behaviour tree. The other good part is that a behaviour tree is a good representation and mimic pattern. I will describe for my tree-matching module a pattern of tree and this pattern is easily transformed into a behaviour tree using the concurrent abstraction. For example, here, this is a generic representation of pattern matching with data structure in Python. I begin to match a value. If this value is of the correct type, if this value type is inside the attribute name, if this value is OK concurrently, I could match other things that could exist inside the pattern data tree. With all this, I could easily translate my pattern into a behaviour tree. And it's also versatile because my need is to do traversal in bottom-up to allow reconstruction. But in fact, if you change some line of code, you have again a top-down pattern matcher. So it's completely versatile. You could use it in both ways. So let's create a generic Python tree. I create a class. I just do a mapping of k-words, parameters inside my attributes. So with my class, I could simulate any class with attributes. I create also something related to a dictionary to simulate the things that you could also match a dictionary, to match a key or the value part of a dictionary. The same thing for a list. And this could be a small part of a data tree that represents our challenge. So I could have an attribute and a list. Inside a list, I could have a dictionary, things like that. And to handle this kind of data tree, I need to relate to the basic reflection mechanism of Python with vars and gata.tr to iterate through attributes. And some types of collections, modules, like mapping, it's possible to know if my object is like a dictionary or is like a list. And use yield and yield form because my work traversal function will be used as a generator. And my work traversal function is also recursive. So I will send notifications through a yield statement. But my function is recursive. So my recursion must be yield form. If you understand the previous presentation, you understand why you use yield form here. Okay, this is a generic pattern of a universal working function that iterates for any tree in Python. I'll hide some data here. The big step is to identify what kind of tree I traverse. So my tree is it related to mapping or an iterable. And at the end, I directly iterate through common attributes. At each part, I yield from recursively my work function into the child. So this piece of code iterates any data tree. And at each IDEN port, in fact, I do notification. I do notification to yield. Okay, now I am matching a value. This is a value of the data. I have matching a type. This is the type. This is the name of the tree. This is the name of the key. This is the index of the list. With all this information, I could send it to a behavioral tree that compose and do pattern matching. And with this, I could identify a value or any value type, a component attribute, a list or dictionary, list, attributes, et cetera. So with all this stuff, I have one pattern, one subtree identified. But I need to do some more smart stuff because you could have tree inside trees, things like that. So I need just to identify a signal tree but a forest. So to identify forest, in fact, one pattern is correctly one behavioral tree. But in fact, I do N-concurrent pattern N-behavior trees with concurrent abstraction. When I work and traverse my tree, I must be aware of the storing of status and positioning inside my tree. So I can't store it inside the behavioral tree because the behavioral tree represents the pattern, not the actually partially identified sequence. So I need to create another store to store this sub-element. So my self.status, my privacy self.status that allow me to store the current status of a behavioral tree are now stored in the user data. User data is another parameter provided to the behavioral tree. So you have the behavioral tree that represents the structure of the pattern and all the data and current element are defined by another structure. And you need also to clean because you begin to identify with your behavioral tree and sometimes behavioral tree fails. So you need to clean up during the traversal of trees to be aware when a correct sequence are reached. Okay, I took all this and I put it on the module called tree matching on my GitHub. Soon I will distribute it in the PIP. Basically, you could use a bunch of class that allow you to describe pattern. In fact, it was an embedded data cell through Python classes. So you could have, for example, match any type with the class any type. At any index, I want a tip, with this value, et cetera, et cetera. I could describe attribute and precisely this attribute. I want a full of tip int for any value. I don't care. I put it, I describe my pattern as a encapsulation of class instantiation. I send it to my bare matching battery and after that I use a match method on my data tree and the stuff are done. You could manage all these things. You could capture nodes and call back functions. After some cleaning and bugging, I need to write some documentation. After all that, I could send the module on PIP. Okay. I don't think we have a question. No? One question? One question? Any question? No? Okay. Thank you.