By Stefan Ianta, Co-Founder, Ianta Labs | November 17, 2015
[As community content, this post reflects the views and opinions of the particular author and does not necessarily reflect the official stance of Neo4j.]In the previous post of this series, we saw that for simple problems, like the three jars problem, we could describe various states with just a few key-value pairs (to store volume and content values for each container) organized maybe in a simple table or CSV file.
It would be easy to see that for each relevant type of object in the problem we would need to know the list of properties, and we would have a row of property values in a CSV file.
So in general we’d need to deal with several tables in more complicated problems and occasionally we might want to build a whole hierarchy of tables just to completely describe a current context. This hierarchy of tables can also be seen as a tree, which is just a particular kind of graph.
Turning an HTML File into a Graph
But what should we do if one or more of the objects in the problem is an HTML file, a code file or a natural language text file which we’d need to change or process somehow?
Let’s first consider the HTML file.
A programmer “knowing” HTML would “see” or understand that file not just as a text file but also as a tree of objects – the famous DOM – Document Object Model, which again is a graph. The programmer then turns out any meaningful (compiling without errors) code files that can also be understood as graph trees (syntax trees).
Overall, we’ll consider that any current context of a problem can be completely described by a set of tree graphs and a list of all eventual relations between their nodes.
A new context for the problem will usually be based on the previous context graph on which some object properties will be changed or new objects will be added or some objects will be excluded.
We will call a change from one context graph to another context graph a microservice. Then a solution to a problem will be represented by a path of microservices that modify the context graph to a state which will fulfill all the constraints of the problem.
If you feel it necessary, you can check in the previous post how we changed step-by-step simple graph contexts using only one microservice for pouring liquids until we reached a target context.
A Social Profiling Example
Now let’s consider a programming problem.
Suppose you are an entrepreneur eager to build your awesome team. You’ve just learned about the great online profiling service offered by www.analyzewords.com and you spent hours exploring profiles of friends and people you’d like to work with.
Here’s an example of Marc Andreesen’s profile as of Nov 1, 2015:
Wouldn’t be nice to see a number of profiles at the same time? And eventually to have automatically calculated some statistics on the shown profiles? Or at least the average profile of the team?
It won’t be difficult to write down in a spreadsheet the vectors of the profiles and script in an average. But it would be time-consuming, and it would be a great exercise to combine several microservices into a web app which should automatically produce a web page with several – let’s say three – people’s profiles, along with the average profile of the team.
So, if you’re wondering what would be the best team to initiate an Internet of Software Microservices, you’d likely be able to quickly build pages like this:
And here we’ll speculate again how Turing would have observed a programmer problem solver building his web app to produce such pages using Cypher-annotated microservices.
Closing the Gap between Initial and Target Context
The first thing the solver will do (consciously or not) would be to figure out the difference or the gap between the initial context – likely containing just a list of Twitter handles – and the target context – which should be a graph describing the details of the browser screenshot above.
To start building the gap, the programmer would first need to use some kind of microservice which would simply add to the graph description of a blank HTML file to the current context, like this:
Such a microservice would have a simple function to build an HTML file entity node in the context graph and to create and append to that node a tree DOM graph like this:
A second simple microservice to use would be to create and link to a specific node (in this case the “body”) of the context graph a tree representing a blank table:
Then the programmer should use some microservices ideally available from the team at AnalyzeWords (AW) that would link to the blank cells in the table DOM tree graphs similar to those generated on AW pages.
For example, one such microservice should have as input at least a Twitter handle and as output the whole DOM graph from AW, including the labels for the profile fields and pop-up explanations for the profile fields.
A second microservice will just link a profile tree structure without the labels to a context DOM node.
Another microservice will just generate and link to the initial list of Twitter handles the profile numeric vector calculated by the AW algorithm.
Then, a simple statistical microservice will receive a list of vectors and calculate its average vector and finally an AW microservice could map a vector on an AW DOM tree graph and connect it to a cell table node.
For the sake of simplicity, we’ll just show (below) the intermediary context graph where just one of the table cell nodes is linked with an AW profile tree equivalent to the intermediary HTML file starting with the lines below:
And here is the screenshot of the intermediary DOM graph from the Neo4j console:
The final DOM graph in this context can then be serialized in a HTML file, which will look similar to the target context the programmer started with.
To some extent such an algorithmic process for solving a web app problem would appear similar to the operations of modifying successively DOM trees in jquery except that here the trees are Neo4j graphs.
The microservices will need to be annotated with Cypher queries which will extract from the current graph of the context the required input for the function making. Thus, the microservices are available for automatic re-combinations in new contexts until all the gaps or differences between the initial and target context of the problem are covered.
The work of a web developer building such a page might seem quite different as he is using some editor to build a HTML file, but arguably, in his or her mind the steps taken could have a representation equivalent to evolving a DOM graph as described above.
In a future post, it might be easier to see how such Cypher-annotated microservices can be used to build a parse tree which can be later serialized in source code.
Learn how to solve problems just like this one using Neo4j. Click below to get your free copy of the Learning Neo4j ebook and learn to master the world’s leading graph database.
Catch up with the rest of this series on an automated market of Cypher-annotated microservices:
About the Author
Stefan Ianta, Co-Founder, Ianta Labs
Stefan Ianta MBA, PMP is an entrepreneur, IT project manager and coder. He co-founded Ianta Labs with his son Alex Ianta who is a Dalhousie CS student. This summer, with their project, Graph Reactor – a Google for software – they were part of Propel ICT startups cohort in Halifax. He can be reached on Twitter at @v_ianta.
Share your Graph Story?
Email us: firstname.lastname@example.org
Have a Graph Question?
Reach out and connect with the Neo4j staff.Stackoverflow