## Wiki80 is a semantic information network, designed to be used both ## by carbon- and silicon-based life. ## Copyright (C) 2018 Davis Remmel ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . # This is my playground for prototyping ideas. ## EXPERIMENT 1: OBJECT STRUCTURE ## This experiment is meant for the purpose of learning about relational ## models, and how to write algorithms to slice through (creating ## views). This is the kernel idea of this project. # Let's define some types. Types beginning with a period are 'hidden'. # Each type is defined at depth:0, and that type's properties are # defined at depth:1. If the value of a property is a string, it is # considered to be the name of another type, and inherits those # properties. In the case of types['.string'], we can see it has a # property 'value' set to None, which ends the graph. # We are going to imagine this in the context of 'people' and 'devices', # where instances of people (a person) form relationships with instances # of devices (a device). types = { 'device': { 'serial': '.string' }, 'person': { 'name': None, 'age': None, 'device': 'device' } } # Instances are literal creations of a type. They are able to set values # to keys defined in their type. They are also able to instead define a # value as a reference to another instance, via the Instance ID (shown # below as 'id_1'. class Instance: itype = None idef = None iid = None def __init__(self, iid, itype, idef): self.iid = iid self.itype = itype self.idef = idef def prop(self, prop): try: found = self.idef[prop] except: return None return found def page_data(self): # This function will render this instance as a jinja-friendly # dict. It gets filled in as a pipeline within this scope. rendered_page = { 'title': '', # Object title (one day pretty) goes here 'data': [], # Object data goes here 'sections': [] } # Linkbacks go here rendered_page['title'] = self.iid # What data types are linked to us? For now, I have these links # pre-defined, but in the future we should crawl the graph to # find them without redundant data. for dname in self.idef: definition = self.idef[dname] # The definition is always an array, but sometimes an array # of one. As in LISP, [None] is equivalent to None. # Go through the definition and see how many are references. # Also, TODO: make this into a map function? for s in definition: ret_key = '' ret_val = '' if callable(s): inst = s() ret_key = 'link' ret_val = '%s:%s' % (inst.itype, inst.iid) else: ret_key = dname ret_val = s rendered_page['data'].append({ 'key': ret_key, 'value': ret_val }) return rendered_page instances = {} instances['id_2'] = Instance('id_2', 'device', { 'serial': [ '1' ], 'person': [ lambda: instances['id_1'] ] }) instances['id_3'] = Instance('id_3', 'device', { 'serial': [ '2' ], 'person': [ lambda: instances['id_1'] ]}) instances['id_1'] = Instance('id_1', 'person', { 'name': [ 'Davis' ], 'age': [ '25' ], 'device': [ lambda: instances['id_2'], lambda: instances['id_3']]}) # That should be enough to create a formal graph. I have prefixed the # references with 'ref:', so I'll use that later to tear it apart from # a normal value. For now, let's see if we can load this into a graph # object and get some views (data slices) out of it. class Graph: context = None types = None instances = None def __init__(self, types, instances): self.types = types, self.instances = instances def get_instance(self, instance_id): try: instance = instances[instance_id] except: return None return instance my_graph = Graph(types, instances) # Let's have a challenge here: show the full 'page' of any particular # object id. This page should show the object's definition, along with # the links from each type. instance = my_graph.get_instance('id_1') print instance.page_data()