SkillAgentSearch skills...

SemanticDB3.1

A c++ implementation of the Semantic DB.

Install / Use

/learn @GarryMorrison/SemanticDB3.1
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Semantic DB 3.1.1

This project is a C++ rewrite of the original python Semantic DB. It is itself now deprecated by version 4, which is available with both a command line and a graphical user interface. SDB4 includes bug fixes, new operators and various improvements, and is a full super-set of SDB 3.1.1, so there is now no reason to use this version at all.

What is the Semantic DB

The SDB is a mathematical notation to represent states of a system, and changes in state of that system. We represent states using kets and changes in state with operators. That's it. Everything else is built on top of this premise. This notation can be used to represent knowledge in say the semantic web, graph databases, and more speculatively, neural circuits. Indeed, the notation is intended to be general, and represent almost anything of interest.

What are Kets

The essence of a ket is a string, float pair, with a slightly unusual notation borrowed from quantum mechanics. Mathematically, the string can be considered the label for a basis element in a vector space, and the float is the corresponding coefficient. With this in mind, it makes sense that we can add kets together in a natural way, and we call such an object a superposition. Depending on the context, superpositions are a sparse vector in an almost infinte, real valued, abstract vector space (the size of the space is only limited by the finite length of strings), but they can also be lists of objects, or a collection of verticies in a graph, or the currently active nodes in a network, or the currently active synapses in a neural circuit, or a mathematical set of elements, or a fuzzy set of elements, or a collection of objects and their corresponding probabilities, and so on. Because the notation is general, the actual interpretation of a superposition depends on the context. We can also consider changes in superpositions over time, one method to do so is using operators, the other is to consider sequences of superpositions. Sequences are an important addition to the notation because otherwise certain things would be impossible, or at least difficult. It should be noted that sequences of length one are simply superpositions, so a sequence is a more general object than a superposition, which in turn is a more general object than a ket. So if below we refer to an object being a sequence, it may also just be a superposition, or for that matter a single ket. Note that sequences are time ordered lists of superpositions, and superpositions are positions in some vector space, so it is not immediately clear what kind of mathematical object a sequence is. I mean, what is the interpretation of a time ordered list of vectors? But we can work with them nonetheless.

Some Kets

Let us give some concrete examples of kets. The person Fred Smith could be represented as |person: Fred Smith> where the type or category is given explicitly, in this case person. But more commonly we leave out the type: |Fred Smith>. An apple could be written as |food: apple> again, with explicit type, or without the type: |apple>. Seven apples can be written as 7|apple>. Note that if the coefficient is not given, then it is by default 1. If a ket is not in the given superposition, we can add it with coefficient 0, without changing the meaning of that superposition (for some defintion of meaning). If a ket has the empty label |> we call it the empty ket, and is treated as the identity element for superpositions. Ie, we can add it to any superposition, and it will not change the superposition. Kets with negative coefficients are much less common, but usually represent inhibition of some sort (ie, the activation of that node is strongly suppressed). We can of course also represent fuzzier quantities by using non integer coefficients. Slightly hungry might be represented as 0.3|hungry>, and very hungry as 0.9|hungry>. We can also represent probabilities using non integer coefficients, providing the sum of the coefficients in the superposition sum to 1 (this can be arranged using the normalize operator).

What are Operators

In the most general sense, an operator is an object that takes a sequence and returns a new sequence. Given the input type to an operator is the same as the output type, we can easily chain operators into so called operator sequences, where we apply a series of operators to the input sequence. If we consider a sequence as the current position in some abstract space, then an operator acts to change that position. And an operator sequence acts to step through that abstract space. So in some strong sense an operator sequence is a pathway through that space (indeed, if we represent positions on a map with kets, and represent steps between those kets with operators, the operator sequence would be a literal pathway). While kets all look the same once you get used to them, operators in contrast come in a great variety. Indeed, a central focus of the semantic db project is working out what operators are useful or required to complete some task. Thankfully the code is modular, so adding new operators to the operator library is relatively easy.

Linear Operators

The simplest operators are linear, and can be considered a type of sparse matrix multiplication. They also work with sequences, and preserve the sequence structure (ie, a kind of generalization of the definition of linear). So for example if some operator op is linear then we have the following property:

op (c1|x> + c2|y> + c3|z>) == c1 op |x> + c2 op |y> + c2 op |z>

where {c1, c2, c3} are float coefficients, and |x>, |y>, |z> are basis elements. Further, if we have several linear operators, op1, op2, op3, op4 then it follows that an operator sequence composed from them, is also linear:

op4 op3 op2 op1 (c1|x> + c2|y>) == c1 op4 op3 op2 op1 |x> + c2 op4 op3 op2 op1 |y>

And in fact this operator sequence also represents sparse matrix multiplication (a matrix times a matrix is also a matrix). Linear operators also preserve sequence structure, so for example:

op (c1|a> + c2|b> . c3|x> + c4|y> + c5|z>) == c1 op|a> + c2 op|b> . c3 op|x> + c4 op|y> + c5 op|z>

where . is used to separate the superpositions in a given sequence. Here our sequence is length 2.

Sigmoids

We have a further type of operator called sigmoids, which are almost linear, in the sense they preserve sequence structure, but they do change the coefficients of kets. The most common sigmoid is the clean sigmoid that sets the coefficient to 0 if it is less than or equal 0, else 1. But we also have an ReLU sigmoid, that maps any negative coefficient to 0, else leaves it unchanged. The point is, deep learning models should have a compact representation in the semantic db, but unfortunately likely too slow to be practical in most cases. If the required matrices are very sparse however, then the semantic db might be faster.

Non Linear Operators

Most of the interesting operators in the semantic db are actually non-linear. And they are all quite varied in what they do, so it is hard to summarize them. But we do have distinct classes of operators, which is very obvious in the back-end code. We have simple operators that take no parameters such as drop, normalize, pick, etc. We have numeric operators that multiply all the kets in a sequence by a value, such as 7. We have compound operators that take constant parameters, such as table[label, op1, op2] or plus[3]. And finally operators that look like functions, such as srange(|1>, |10>) or arithmetic(|3>, |+>, |5>). And they are further broken down into sub-classes of these, depending on if they require context, or if they respect sequence strucuture or not, and so on. We have a working convention that the sequence version of an operator starts with s. So for example how-many counts the number of kets in a superposition, meanwhile show-many counts the number of superpositions in a sequence. Or split splits a ket into a superposition, and ssplit splits a ket into a sequence, and so on.

ContextList

So above we mentioned representing knowledge, but haven't yet presented how to do so. This is where context and learn rules come in (see next section). A context is simply a collection of knowledge that is distinct, and fully independent from, other collections of knowledge that we may have. Think of them a little like a namespace in a programming language, or a scope. So for example your knowledge about your friends might be better represented as distinct from your knowledge about your work colleagues. This might look a little like:

|context> => |friends>
... some knowledge about friends ...

|context> => |work colleagues>
... some knowledge about work ...

A context list is a collection of different contexts. To see the contextlist in the semantic db shell, enter: dump multi.

Learn Rules

Finally, we are ready to describe learn rules. A learn rule is what we use to associate a sequence with a given ket, labelled with an operator. After we have done so, that operator applied to that ket will return the learnt sequence. Recalling that when we say sequence it can be a proper sequence, or a superposition, or just a ket (the latter are just special types of sequences). Say we want to learn a little knowledge about Fred:

full-name |Fred> => |Fred Smith>
mother |Fred> => |June>
father |Fred> => |Robert>
age |Fred> => |34>
friends |Fred> => |Jack> + |Sam> + |Emma> + |Liz>
spelling |Fred> => |F> . |r> . |e> . |d>

where the general structure for a learn rule is:

operat
View on GitHub
GitHub Stars7
CategoryDevelopment
Updated3y ago
Forks3

Languages

C++

Security Score

70/100

Audited on Mar 2, 2023

No findings