universal-meaning-map / mind-map

Global domain mind map tool build on top of IPFS and IPLD
https://github.com/interplanetarymindmap/mind-map
14 stars 1 forks source link

Original data structure #7

Open xavivives opened 5 years ago

xavivives commented 5 years ago

Nodes in the global domain

For Global domain we understand that there is only one single giant mind map.

Which means that we need to be able to break in down into smaller subsets/pieces. The atomic piece of a mind map is what until now we've called a node (which is a very conflicting name that we would like to change).

A node is nothing but a set of relations around a concept/content/idea. We call this "concept" origin. So the origin is the data that represents where the relations are coming from.

These relations are towards another piece of data. From the node perspective, we call these data targets.

This implies that each node needs to contain and describe the relations with all the other targets it is interested in because if broken apart, it will lose information it cares about.

In other words, relations come out of the origin, never in (at least from the origin perspective). If that was the case we will have a duplicated source of truth (the relation from the incoming origin and the relation from the current origin). This does not mean that the relation can't represent an incoming direction.

It makes a node behave selfishly, which is the logical behaviour in a distributed system.

Since we're in a global domain we will need to represent a subset of the global mind map. Which will be just a list of nodes.

Relationships and nodes

We understand relation as of how a piece of data (origin) relates to another piece of data (target). A node can have an arbitrary number of relations.

    {
        "origin":"content1",
        "relations": [
            {"target": "content2"}
            {"target": "content3"}
        ]
    }

Relationship types

One of our frustrations and things we are exploring in detail is how can we extend how do we relate to information beyond what a user interface or the underlying system allows.

In this case, it translates on allowing the user to define how a piece of information relates to another. So a relation can have a type, which is nothing but a reference to an expression of the type of relation.

A type of a relation could be "depends on", "is my dad", "contains"... or anything (text or not). It is the job of the render to understand what this type means and how to represent it.

Because the selfish behaviour of a node described above, a relationship is always described from the perspective of the origin towards the target

[
    {
        "origin":"Son",
        "relations": [
            {
                "target": "Dad",
                "type": "Is my dad"
            }
        ]
    },
    {
        "origin":"Dad",
        "relations": [
            {
                "target": "Son",
                "type": "Is my son"
            }
        ]
    }
]

The selfish behaviour implies that there is no way to guarantee the integrity of the information since the nodes could express conflicting information. And that's ok because each node have its own truth.

[
    {
        "origin":"Son",
        "relations": [
            {
                "target": "Dad",
                "type": "Is NOT my dad"
            }
        ]
    },
    {
        "origin":"Dad",
        "relations": [
            {
                "target": "Son",
                "type": "Is my son"
            }
        ]
    },
]

Merkle paths as identifiers

In the previous examples, we've used sample text in the origin field, to uniquely identify a piece of data. This was just used for explanation purposes. It does not make sense in a global domain. And identifier needs to be global.

We first thought about using the CID of the content. This is basically its hash, but then we realized that a merkle-path was a better choice.

Both the CIDs and the merkle-paths are unique global identifiers. But the merkle-path allows pointing to mutable content (if referencing to an IPNS link). Plus a CID can be represented as merkle-path as well.

This also allows us to not have to dereference the merkle-path in order to obtain the CID.

The data structure

Considering all the above, a representation of a node as an IPLD object looks like this:

{
    "origin": {
        "link": {
            "/": "ipfs/QmUmg7BZC1YP1ca66rRtWKxpXp77WgVHrnv263JtDuvs2k"
        }
    },
    "relations": [
        {
            "target": {
                "link": {
                    "/": "ipfs/zdpuAvYJaZxBjTV4WH3irwThm5t2a7yTccoN9cWpDmtV4CiNz"
                }
            },
            "type": {
                "link": {
                    "/": "ipfs/zdpuAvYJaZxBjTV4WH3irwThm5t2a7yTccoN9cWpDmtV4CiNz"
                }
            }
        },
        {
            "target": {
                "link": {
                    "/": "ipfs/zdpuAyvmoJWTiVrCv1aCHV5xUZ1fxUf4XLkrprKPMMFCNKfj3"
                }
            }
        }
    ]
}