Skip to content

Commit

Permalink
Add 'symbolic-ai/eva2022/' from commit 'af1a571d26f98eef2502b6932bcc7…
Browse files Browse the repository at this point in the history
…1141d4bf942'

git-subtree-dir: symbolic-ai/eva2022
git-subtree-mainline: 19a8fbf
git-subtree-split: af1a571
  • Loading branch information
generic-github-user committed Sep 1, 2022
2 parents 19a8fbf + af1a571 commit 433f39f
Show file tree
Hide file tree
Showing 28 changed files with 1,463 additions and 0 deletions.
150 changes: 150 additions & 0 deletions symbolic-ai/eva2022/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Eva
eva-db*
prevdata.*
*.evab
customize.py
cache*
ignore_*

# LaTeX
*.synctex.gz
*.pdf
*.aux
*.fdb_latexmk
*.fls

# venv
bin/*
lib64
*.cfg


# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/
Empty file added symbolic-ai/eva2022/__init__.py
Empty file.
24 changes: 24 additions & 0 deletions symbolic-ai/eva2022/architecture/architecture.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
\documentclass{article}
\begin{document}
The modern version of Eva is implemented in a functional style that maintains a single global state which is read from and written to sequentially; the command flow is completely synchronous and as such it is (at least theoretically) well-adapted for debugging and analysis.

Eva's underlying data structure would likely best be described as a "weakly typed metagraph", one of the most general possible forms of a graph data structure in which the distinction between nodes/vertices and edges is eschewed and a graph consists only of a single type of object. This atomic unit (generally referred to as a node) contains some value and an ordered (possibly empty) set of other nodes (in practice, node references).

A traditional directed edge between two nodes can therefore be represented as an ordered pair of nodes, with the associated value determining their relationship. I have found this to be an empirically effective model for handling complex, dynamic data with a frequently changing schema and a requirement to be able to add additional properties to even the most basic, fundamental objects present in the database.

Some notation:
\begin{itemize}
\item $G$ - a metagraph (i.e., a set of nodes)
\item $G_i$ - a specific node (tuple of index, value, and subnodes)
\item $r_i$ - a list of nodes that reference node $G_i$
\end{itemize}

Attributes such as data types are handled at the database level - that is, the implementation does not specify node types or directly operate on them. In practice, "type" edge-nodes are generated as needed to link individual nodes to other nodes that specify the types corresponding to their values. As a matter of implementation, it is of course possible to "roll" external attributes into objects used to represent nodes if every or nearly every node will have a given property.

With that in mind, we also define the following functions:

\begin{itemize}
\item $e(G, x)$ - expand a binary (edge) node such that $e(G, (v, (a, b))) = (\emptyset, (a, c)), (v, \emptyset), (\emptyset, (c, b))$
\item $f(G, v)$ - search for a value in the graph
\end{itemize}
\end{document}
60 changes: 60 additions & 0 deletions symbolic-ai/eva2022/arithmetic_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#
# simpleArith.py
#
# Example of defining an arithmetic expression parser using
# the infixNotation helper method in pyparsing.
#
# Copyright 2006, by Paul McGuire
#

# Adapted from https://github.com/pyparsing/pyparsing/blob/master/examples/simpleArith.py

import sys
from pyparsing import *

ppc = pyparsing_common

ParserElement.enablePackrat()
sys.setrecursionlimit(3000)

integer = ppc.integer
variable = Word(alphas, exact=1)
operand = integer | variable

expop = Literal("^")
signop = oneOf("+ -")
multop = oneOf("* /")
plusop = oneOf("+ -")
factop = Literal("!")

arith = infixNotation(
operand,
[
("!", 1, opAssoc.LEFT),
("^", 2, opAssoc.RIGHT),
(signop, 1, opAssoc.RIGHT),
(multop, 2, opAssoc.LEFT),
(plusop, 2, opAssoc.LEFT),
],
)

test = [
"9 + 2 + 3",
"9 + 2 * 3",
"(9 + 2) * 3",
"(9 + -2) * 3",
"(9 + -2) * 3^2^2",
"(9! + -2) * 3^2^2",
"M*X + B",
"M*(X + B)",
"1+2*-3^4*5+-+-6",
"(a + b)",
"((a + b))",
"(((a + b)))",
"((((a + b))))",
"((((((((((((((a + b))))))))))))))",
]
# for t in test:
# print(t)
# print(arith.parseString(t))
# print("")
20 changes: 20 additions & 0 deletions symbolic-ai/eva2022/backup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from datetime import datetime
from helpers.getsize import getsize

import zlib
import pickle

from say import say

def backup(database):
date_format = '%m_%d_%Y, %H_%M_%S'
backupPath = f'./eva_{datetime.now().strftime(date_format)}.evab'
with open(backupPath, 'wb') as fileRef:
nodeList = list(map(list, database.nodes))
B = zlib.compress(pickle.dumps(nodeList))
fileRef.write(B)
say(database, f'Backup saved to {backupPath} [{getsize(B)} bytes]')
# return backupPath

callNode = database.addNode('backup', [], True)
return callNode
11 changes: 11 additions & 0 deletions symbolic-ai/eva2022/commandhandler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
command_list = {}

def command(prefix):
if not isinstance(prefix, str):
raise TypeError

def command_decorator(func):
# commands.append(func)
command_list[prefix] = func
return func
return command_decorator
1 change: 1 addition & 0 deletions symbolic-ai/eva2022/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__all__ = ['quit', 'query', 'find', 'loadbackup', 'crawl']
26 changes: 26 additions & 0 deletions symbolic-ai/eva2022/commands/crawl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from commandhandler import command
from globals import Eva

import os
from helpers.filehandling import scanDir

from helpers.timefunc import timeFunc
from say import say

@command('crawl')
def crawlCommand(newInput):
database = Eva.database
def crawlWrapper():
p = newInput[6:]
say(database, f'Scanning {p}')
scan = database.addNode('file_scan', [], True)
c = 0
for d in os.scandir(p):
scanDir(database, None, d, c, scan)
say(database, 'Done')
# !
return scan
timeFunc(database, crawlWrapper)()

# TODO: assess database characteristics using statistical tests on sampls of nodes
# TODO: line numbering
22 changes: 22 additions & 0 deletions symbolic-ai/eva2022/commands/find.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from commandhandler import command
from globals import Eva
database = Eva.database

import functools
from helpers.timefunc import timeFunc
timeFunc = functools.partial(timeFunc, database)

from say import say

@command('find')
@timeFunc
def findCommand(newInput):
# def findInner():
# TODO: clean this up
searchNode = database.addNode('search_cmd', [], True)
database.addNode('source', [searchNode, inputId])
results = list(filter(lambda x: isinstance(x.value, str) and (newInput[5:] in x.value), database.nodes))
for n in results:
print(n)
database.addNode('origin', [n.id, database.addNode('eva_output', [], False)])
return searchNode
27 changes: 27 additions & 0 deletions symbolic-ai/eva2022/commands/loadbackup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from commandhandler import command
from globals import Eva
database = Eva.database

from say import say

import pickle
import zlib

@command('loadbackup')
def loadbackupCommand(newInput):
with open('eva_03_17_2022, 11_41_04.evab', 'rb') as fileRef:
database.nodes = pickle.loads(zlib.decompress(fileRef.read()))
# TODO
database.nodes = list(map(lambda n: database.nodeTemplate(*n), database.nodes))

database.references = []
print(f'Building reference lists for {len(database.nodes)} nodes')
for i, n in enumerate(database.nodes):
if (i % 1000 == 0):
say(database, f'Processed {i} nodes')
if n.value not in ['origin', 'accessed', 'source', 'type']:
database.references.append([m.id for m in database.nodes if (n.id in m.members)])
else:
database.references.append([])
print('Done')
database.save()
Loading

0 comments on commit 433f39f

Please sign in to comment.