# Variable propagation

Can someone help explain variable propagation in details ? I am not sure how it works.
Here is an example from docs. I do not understand

1. how “math(paths / (num_films/paths))” can be fraction ?
2. why is “math(num_films/paths)” always the same as “num_films” ?
3. Why is “math(num_films)” not always the same, i.e., should be the same as total_nums?
``````curl localhost:8080/query -XPOST -d '{
movie_fraction(func:eq([email protected], "Peter Jackson")){
uid
paths as math(1)
total_films : num_films as count(director.film)
director : [email protected]

director.film {
starring {
performance.actor {
path: math(paths)
xx: math(num_films/paths)
*fraction : math(paths / (num_films/paths))*
actor : [email protected]
}
}
}
}
}' | python -m json.tool | less
``````

Results:

``````{
"data": {
"movie_fraction": [
{
"total_films": 0,
"director": "Peter Jackson"
},
{
"total_films": 0,
"director": "Peter Jackson"
},
{
"actor": "Tim McLachlan",
"director": "Peter Jackson",
"fraction": 0.052632,
"path": 1,
"total_films": 19,
"xx": 19
},
{
"actor": "Thomas Rimmer",
"director": "Peter Jackson",
"fraction": 0.052632,
"path": 1,
"total_films": 19,
"xx": 19
},
{
"actor": "Jeffrey Thomas",
"director": "Peter Jackson",
"fraction": 0.105263,
"path": 2,
"total_films": 19,
"xx": 19
},
{
"actor": "Cate Blanchett",
"director": "Peter Jackson",
"fraction": 0.315789,
"path": 6,
"total_films": 19,
"xx": 19
},
...
...
...
``````

The blogpost on recommendation engines does a good job of explaining variable propagation. It is best understood by drawing a graph and calculating the value of a variable at different levels

The blogpost mentions:

In short, the value that a node receives is equal to the sum of values of all its parent nodes.

You could try with a smaller query on `https://play.dgraph.io` and try to correlate the graph response with the JSON.

``````{
movie_fraction(func:eq([email protected], "Peter Jackson")){
uid
paths as math(1)
total_films : num_films as count(director.film)
[email protected]

director.film (first: 5) {
starring(first: 5) {
performance.actor {
path: math(paths)
xx: math(num_films/paths)
fraction : math(paths / (num_films/paths))
[email protected]
}
}
}
}
}
``````

which produces the following Graph

and has the following JSON response

``````{
"data": {
"movie_fraction": [
{
"uid": "0x8b77c",
"val(paths)": 1,
"total_films": 0,
"[email protected]": "Peter Jackson"
},
{
"uid": "0x1cdf22",
"val(paths)": 1,
"total_films": 0,
"[email protected]": "Peter Jackson"
},
{
"uid": "0x764275",
"val(paths)": 1,
"total_films": 19,
"[email protected]": "Peter Jackson",
"director.film": [
{
"starring": [
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Tim McLachlan"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Thomas Rimmer"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Jeffrey Thomas"
}
]
},
{
"performance.actor": [
{
"path": 2,
"xx": 19,
"fraction": 0.105263,
"[email protected]": "Cate Blanchett"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "William Kircher"
}
]
}
]
},
{
"starring": [
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Craig Hall"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Lee Hartley"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Lee Donahue"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Julie Holmes"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Jim Knobeloch"
}
]
}
]
},
{
"starring": [
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Anthony Ray Parker"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Elizabeth Hawthorne"
}
]
},
{
"performance.actor": [
{
"path": 2,
"xx": 19,
"fraction": 0.105263,
"[email protected]": "Stuart Devenie"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "William Pomeroy"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Angela Bloomfield"
}
]
}
]
},
{
"starring": [
{
"performance.actor": [
{
"path": 2,
"xx": 19,
"fraction": 0.105263,
"[email protected]": "Stuart Devenie"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Donna Akersten"
}
]
}
]
},
{
"starring": [
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Hugo Weaving"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "James Nesbitt"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Christopher Lee"
}
]
},
{
"performance.actor": [
{
"path": 1,
"xx": 19,
"fraction": 0.052632,
"[email protected]": "Ken Stott"
}
]
},
{
"performance.actor": [
{
"path": 2,
"xx": 19,
"fraction": 0.105263,
"[email protected]": "Cate Blanchett"
}
]
}
]
}
]
},
{
"uid": "0x7dc6b0",
"val(paths)": 1,
"total_films": 0,
"[email protected]": "Peter Jackson"
}
]
}
}
``````

As you can see from the JSON response, only `Cate Blanchett` and `Stuart Devenie` have value of `path` as 2 which is also observable from the graph since they have two incoming edges. Remember, the value of a variable at a node is the sum of values of the variable for its parent nodes.

This is because both `num_films` and `paths` are defined at the same level, so the ratio of their values would remain the same at every level.
I think you meant same as `total_films`. A variable has different value at different depths i.e. what we call variable propagation. So the value at a level would depend on the sum of the value of a variable at the parent nodes.
We convert an integer variable to `float` before passing it to the division(/) operator and as value of `paths` is less than value of `num_films/paths` you end up with a fraction. I’d definitely recommend reading the section on Variable propogation in the blogpost.