Expertsystemen

 

Calling graphs

To call a graph you use a callgraph icon callgraph action (Actions > Call Graph). The simple way is translated as a callnext in the source. You can also click ‘iteration’, then the call will be translated as call graph[x] (x is the iteration) in the source. It is important to understand how callnexts and calls are used to make sure nothing goes wrong. The call using an iteration is always clear, a call to graph X iteration 1 is always graph X iteration 1. If you change your model, calling the graph X from node A instead of B, the call will still be graph X iteration 1. But using callnext, the story is a bit more complex. The callnext used in node A will create the graph with a iteration ‘last iteration + 1’ with a remark that it is called from A. Calling the graph from B will get you another graph. Look at the following example.

Callnext

Callnext will look at all graphs, and create a new one, with a new iteration. So the first time callnext ginfo is called, a graph ginfo with iteration 0 is created, and executed. The second time a callnext is executed, the software will see the first iteration, and create a new graph, namely ginfo with iteration 1.

In the model callgraphsdemo.mdl there is a start node, then 2 calls, then a node where the choice is made to go left or right. In both nodes the same graph is called (ginfo) with a simple call (so a callnext). If you walk to the right node, the graph iterations will look like this:

ginfo[0]  (called from callnexts)
ginfo[1]  (second time from callnexts)
ginfo[2]  (called from right)

if you insert a value in the ginfo graph called from the right (e.g. ‘hello’), and go back, choose left, the value will be empty. You can insert a value, go back, choose right, and the original value ‘hello’ will show. The server does not only look at the iterations, it also checks where the graph is called from. So internally, if you go back from the right node to the left, the list will be like this:

ginfo[0]  (called from callnexts)
ginfo[1]  (second time from callnexts)
ginfo[2]  (called from left)
hidden ginfo[3]  (called from right)

If you go back to the choice, the list will be like:

ginfo[0]  (called from callnexts)
ginfo[1]  (second time from callnexts)
hidden ginfo[2]  (called from left)
hidden ginfo[3]  (called from right)

If you choose right, the server will ignore iteration 2, see that iteration 3 is the one we want, and change the order:

ginfo[0]  (called from callnexts)
ginfo[1]  (second time from callnexts)
ginfo[2]  (called from right)
hidden ginfo[3]  (called from left)

Call (with iteration)

In the model we now go to node decisionwithcalls. Again, we choose left or right, but in the following nodes, both of them call ginfo with iteration 4. If you go right, give as value ‘sunshine’ and go back, choose left, the value ‘sunshine’ will be already there. So, calling with the iteration forces the server to take that iteration. if we continue to node calltoiteration4, you can see a call to that iteration 4 yet again. But, if you play the model, you will find that the graph is not executed. This is because the graph is already executed.

With the forcing of the iteration, you can have a model which will ask the user if he wants to join the team, and if so, call ‘gcar’. In that graph the user is asked if there is a car, and if so, what kind of car. If later on, another question comes by: ‘does the user want to help the team’, and the answer is yes, you can call that same graph ‘gcar’ again. If the user already passed it, because he joined the team, the questions will not show, but if not, the graph is executed.

Quotes

Quotes ( ^{graphname.nodename.data} ) on screen or in text fragments are very powerful. But it can be confusing or prone to errors if callnexts are used. A quote can be hard-coded to the iteration of the graph using ^{graphname[X].nodename.data} where X is the iteration. Mostly the iteration is not given: ^{graphname.nodename.data}. Now the server has to figure it out, and it does so like this:

Say there is a graph Z[0], called from graph main. We have graph main also calling X[1], calling Y[2]. We quote from Y.

We quote `Y.node.data’. The server will see that we are on Y, iteration 2, so it will get the data of iteration 2: Y[2].node.data

We quote ‘X.node.data’. The server will see that the quote is not from Y, and will follow all the calling graphs (until main). It sees Y being called by X. And it will take iteration 1, because X[1] was calling. So X[1].node.data

We quote ‘Z.node.data’. Quoting outside the graph is tricky. The server will see that Z has nothing to do with Y or the calling graphs. It will look at the same iteration as Y, 2, and look for Z[2]. Failing, because there is no Z[2], it will fall back to Z[0], which does exist. So Z[0].node.data. But if we had the same situation as in the example model, it is quite possible that there are ‘hidden’ graphs, called from nodes which are not in the path anymore, or from a case where in the first version the graph was called from A, but now from B. In this case, there is a Z[2], but it is hidden. Now the server will not fall back to 0, but will see iteration 2, see it is hidden, and return ‘’. So if you are quoting outside the graph, not from the callings graphs, be aware of the hidden graphs. In this case, use a Z[0].node.data to make sure you are quoting the right graph.