summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorolpc user <olpc@xo-5d-f7-86.localdomain>2019-11-24 19:23:37 -0800
committerolpc user <olpc@xo-5d-f7-86.localdomain>2019-11-24 19:23:37 -0800
commitcd03e291664cb102bde61d86a15f0add11809766 (patch)
tree9afb4bc872236b95debd5e20daf00797c563c666
parentdbbed1e4e1d4b3f268c71236c89f1d673fa0c165 (diff)
downloadstandingwithresilience-cd03e291664cb102bde61d86a15f0add11809766.tar.gz
standingwithresilience-cd03e291664cb102bde61d86a15f0add11809766.zip
messy but works. rushing to get this done with may have been a poor investment.
-rw-r--r--starts/meaning-vm/DESIGN.txt6
-rw-r--r--starts/meaning-vm/level-0/concept.cpp6
-rw-r--r--starts/meaning-vm/level-0/level-0.hpp1
-rw-r--r--starts/meaning-vm/level-0/memorystore.cpp6
-rw-r--r--starts/meaning-vm/level-0/ref-mixin.hpp27
-rw-r--r--starts/meaning-vm/level-0/ref.cpp4
-rw-r--r--starts/meaning-vm/level-0/ref.hpp13
-rw-r--r--starts/meaning-vm/level-0/vref.hpp3
-rw-r--r--starts/meaning-vm/level-1/common.hpp10
-rw-r--r--starts/meaning-vm/level-1/concepts.cpp13
-rw-r--r--starts/meaning-vm/level-1/concepts.hpp20
-rw-r--r--starts/meaning-vm/level-1/level-1.hpp7
-rw-r--r--starts/meaning-vm/level-1/ref.cpp91
-rw-r--r--starts/meaning-vm/level-1/ref.hpp34
-rw-r--r--starts/meaning-vm/level-1/sugar.cpp41
-rw-r--r--starts/meaning-vm/level-1/sugar.hpp47
-rw-r--r--starts/meaning-vm/level-1/vref.hpp38
-rw-r--r--starts/meaning-vm/level1.cpp39
-rw-r--r--starts/meaning-vm/makefile5
19 files changed, 386 insertions, 25 deletions
diff --git a/starts/meaning-vm/DESIGN.txt b/starts/meaning-vm/DESIGN.txt
index 299acb2..340f0d2 100644
--- a/starts/meaning-vm/DESIGN.txt
+++ b/starts/meaning-vm/DESIGN.txt
@@ -8,3 +8,9 @@ Each concept has a unique address, and a list of concept pairs it links to.
The first of the pair represents the type of the link, and the second the target.
Concepts may not be deallocated unless nothing links to them.
A special kind of concept is the value, which holds arbitrary data alongside itself.
+
+# LEVEL 1
+Level 1 provides for every concept having a name. There is additionally syntax sugar
+for instantiating and using named or hyphen-separated references.
+Level-1 names are for development ease, and are considered unique. Hence this also
+begins definition of simple shared meaning associated with a name.
diff --git a/starts/meaning-vm/level-0/concept.cpp b/starts/meaning-vm/level-0/concept.cpp
index 579cca8..dace7df 100644
--- a/starts/meaning-vm/level-0/concept.cpp
+++ b/starts/meaning-vm/level-0/concept.cpp
@@ -12,7 +12,7 @@ ref concept::id()
void concept::link(ref const & type, ref const & target)
{
- links.insert({type.ptr, target.ptr});
+ links.insert({type, target});
}
void concept::unlink(ref const & type, ref const & target)
@@ -43,7 +43,7 @@ void concept::unlink(ref const & type)
bool concept::linked(ref const & type) const
{
- return links.count(type.ptr) > 0;
+ return links.count(type) > 0;
}
bool concept::linked(ref const & type, ref const & target) const
@@ -71,7 +71,7 @@ concept::array concept::getAll(ref const & type) const
ref concept::get(ref const & type) const
{
- auto result = links.equal_range(type.ptr);
+ auto result = links.equal_range(type);
if (result.first == result.second) {
throw no_such_link_type(selfref, type);
}
diff --git a/starts/meaning-vm/level-0/level-0.hpp b/starts/meaning-vm/level-0/level-0.hpp
index 10df5b7..b44b6e0 100644
--- a/starts/meaning-vm/level-0/level-0.hpp
+++ b/starts/meaning-vm/level-0/level-0.hpp
@@ -5,6 +5,5 @@
#include "errors.hpp"
#include "memorystore.hpp"
#include "ref.hpp"
-#include "ref-mixin.hpp"
#include "value.hpp"
#include "vref.hpp"
diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp
index 0a4f0cc..7ff5e42 100644
--- a/starts/meaning-vm/level-0/memorystore.cpp
+++ b/starts/meaning-vm/level-0/memorystore.cpp
@@ -26,10 +26,10 @@ static concept* referenced(ref r) {
}
for (auto & l : r2->links) {
if (ref(l.first) == r) {
- return r2.ptr;
+ return r2;
}
if (ref(l.second) == r) {
- return r2.ptr;
+ return r2;
}
}
}
@@ -48,7 +48,7 @@ void dealloc(ref r) {
{
if (ref(*it) == r) {
concepts().erase(it);
- delete r.ptr;
+ delete (concept*)r;
return;
}
}
diff --git a/starts/meaning-vm/level-0/ref-mixin.hpp b/starts/meaning-vm/level-0/ref-mixin.hpp
index ba5fe09..15e5abe 100644
--- a/starts/meaning-vm/level-0/ref-mixin.hpp
+++ b/starts/meaning-vm/level-0/ref-mixin.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <map>
#include <vector>
namespace intellect {
@@ -7,25 +8,33 @@ namespace level0 {
template <typename ref, template<typename> typename vref>
struct refmixin {
+ using links_t = std::multimap<ref, ref>;
using array = std::vector<ref>;
- void link(ref const & type, ref const & target) { ptr()->link(type, target); }
- void unlink(ref const & type, ref const & target) { ptr()->unlink(type, target); }
- void unlink(ref const & type) { ptr()->unlink(type); }
+ void link(ref const & type, ref const & target) { p()->link(conv<r>(type), conv<r>(target)); }
+ void unlink(ref const & type, ref const & target) { p()->unlink(conv<r>(type), conv<r>(target)); }
+ void unlink(ref const & type) { p()->unlink(conv<r>(type)); }
- bool linked(ref const & type) const { return ptr()->linked(type); }
- bool linked(ref const & type, ref const & target) const { return ptr()->linked(type, target); }
+ bool linked(ref const & type) const { return p()->linked(conv<r>(type)); }
+ bool linked(ref const & type, ref const & target) const { return p()->linked(conv<r>(type), conv<r>(target)); }
- array getAll(ref const & type) const { return conv<array>(ptr()->getAll(type)); }
+ array getAll(ref const & type) const { return conv<array>(p()->getAll(conv<r>(type))); }
- ref get(ref const & type) const { return conv<ref>(ptr()->get(type)); }
- void set(ref const & type, ref const & target) { ptr()->set(type, target); }
+ links_t & links() const { return *(links_t*)&(p()->links); }
+
+ ref get(ref const & type) const { return conv<ref>(p()->get(conv<r>(type))); }
+ void set(ref const & type, ref const & target) { p()->set(conv<r>(type), conv<r>(target)); }
template <typename T>
vref<T> vget(ref const & type) const { return conv<vref<T>>(get(type)); }
+ bool operator==(ref const & other) const { return self.p() == other.p(); }
+ bool operator!=(ref const & other) const { return self.p() == other.p(); }
+ bool operator<(ref const & other) const { return self.p() < other.p(); }
+
private:
- inline concept * ptr() const { return conv<ref*>(this)->ptr; }
+ inline concept * p() const { return *conv<concept**>(this); }
+ using r = level0::ref;
template <typename OUT, typename IN>
static inline OUT conv(IN r) { return *(OUT*)&r; }
};
diff --git a/starts/meaning-vm/level-0/ref.cpp b/starts/meaning-vm/level-0/ref.cpp
index 7e10528..f468456 100644
--- a/starts/meaning-vm/level-0/ref.cpp
+++ b/starts/meaning-vm/level-0/ref.cpp
@@ -14,7 +14,7 @@ ref::ref(concept *p)
}
}
-std::string ref::dump(ref skipmarkertype, ref skipmarkertarget) const
+std::string ref::dump(ref skipmarkertype, ref skipmarkertarget)
{
if (self->linked(skipmarkertype, skipmarkertarget)) {
return {};
@@ -25,7 +25,7 @@ std::string ref::dump(ref skipmarkertype, ref skipmarkertarget) const
}
self->link(skipmarkertype, skipmarkertarget);
for (auto & link : self->links) {
- if (link.first == skipmarkertype && link.second == skipmarkertype) {
+ if (link.first == skipmarkertype && link.second == skipmarkertarget) {
continue;
}
ret += link.second.dump(skipmarkertype, skipmarkertarget);
diff --git a/starts/meaning-vm/level-0/ref.hpp b/starts/meaning-vm/level-0/ref.hpp
index c1fa7fa..abe3897 100644
--- a/starts/meaning-vm/level-0/ref.hpp
+++ b/starts/meaning-vm/level-0/ref.hpp
@@ -11,16 +11,19 @@ namespace level0 {
struct ref : public refmixin<ref, vref>
{
ref(concept *p);
+ ref(ref const & other) : ref(other.ptr) { }
+ ref & operator=(ref const & other) { self.ptr = other.ptr; return self; }
operator concept*() const { return ptr; }
concept* operator->() const { return ptr; }
- bool operator==(ref const & other) const { return self.ptr == other.ptr; }
- bool operator!=(ref const & other) const { return self.ptr != other.ptr; }
- bool operator<(ref const & other) const { return self.ptr < other.ptr; }
concept & deref() { return *ptr; }
- std::string dump(ref skipmarkertype, ref skipmarkertarget) const;
+ ref & l0() { return self; }
+ ref const & l0() const { return self; }
- concept * const ptr;
+ std::string dump(ref skipmarkertype, ref skipmarkertarget);
+
+private:
+ concept * ptr;
};
}
diff --git a/starts/meaning-vm/level-0/vref.hpp b/starts/meaning-vm/level-0/vref.hpp
index cffc8f5..1eb701d 100644
--- a/starts/meaning-vm/level-0/vref.hpp
+++ b/starts/meaning-vm/level-0/vref.hpp
@@ -17,13 +17,14 @@ struct vref
vref(T const & val) : vref(alloc(new value<T>(val))) { }
- vref(ref const & other) : ptr(static_cast<value<T>*>(other.ptr)) { }
+ vref(ref const & other) : ptr(static_cast<value<T>*>((concept*)other)) { }
operator ref() { return ptr; }
T const & val() { return *ptr; }
// for use by containers
bool operator<(vref<T> const & other) const { return self.ptr < other.ptr; }
+protected:
value<T> * const ptr;
};
diff --git a/starts/meaning-vm/level-1/common.hpp b/starts/meaning-vm/level-1/common.hpp
new file mode 100644
index 0000000..2977077
--- /dev/null
+++ b/starts/meaning-vm/level-1/common.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace intellect {
+namespace level1 {
+
+struct ref;
+template <typename T> struct vref;
+
+}
+}
diff --git a/starts/meaning-vm/level-1/concepts.cpp b/starts/meaning-vm/level-1/concepts.cpp
new file mode 100644
index 0000000..4c098de
--- /dev/null
+++ b/starts/meaning-vm/level-1/concepts.cpp
@@ -0,0 +1,13 @@
+#include "concepts.hpp"
+
+namespace intellect {
+namespace level1 {
+namespace concepts {
+
+ref is("is");
+ref anonymous("anonymous");
+ref link("link");
+
+}
+}
+}
diff --git a/starts/meaning-vm/level-1/concepts.hpp b/starts/meaning-vm/level-1/concepts.hpp
new file mode 100644
index 0000000..7aa7394
--- /dev/null
+++ b/starts/meaning-vm/level-1/concepts.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "ref.hpp"
+#include "sugar.hpp"
+
+namespace intellect {
+namespace level1 {
+
+namespace concepts {
+
+extern ref name; // used as the link to value<std::string> naming each concept
+extern ref is; // a link to define group relationships, links to the more general class
+extern ref anonymous; // a group given concepts with generated names
+extern ref link; // TODO: for concepts that are links, link them with is=link
+//extern ref true, false; <-- casting provides as if these were declared
+
+}
+
+}
+}
diff --git a/starts/meaning-vm/level-1/level-1.hpp b/starts/meaning-vm/level-1/level-1.hpp
new file mode 100644
index 0000000..d13ba9f
--- /dev/null
+++ b/starts/meaning-vm/level-1/level-1.hpp
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "common.hpp"
+#include "concepts.hpp"
+#include "ref.hpp"
+#include "sugar.hpp"
+#include "vref.hpp"
diff --git a/starts/meaning-vm/level-1/ref.cpp b/starts/meaning-vm/level-1/ref.cpp
new file mode 100644
index 0000000..045e879
--- /dev/null
+++ b/starts/meaning-vm/level-1/ref.cpp
@@ -0,0 +1,91 @@
+#include "ref.hpp"
+#include "../level-0/errors.hpp"
+#include "../level-0/memorystore.hpp"
+#include "../level-0/vref.hpp"
+#include "concepts.hpp"
+#include "vref.hpp"
+
+#include <unordered_map>
+
+using namespace intellect;
+using namespace level1;
+using namespace concepts;
+
+// ensure name link and backing structure are created prior to first use
+static auto & namestruct()
+{
+ static struct name_t
+ {
+ std::unordered_map<level0::vref<std::string>,level0::ref,std::hash<std::string>,std::equal_to<std::string>> conceptsByName;
+ ref nameref;
+ name_t()
+ : nameref(level0::alloc())
+ {
+ level0::vref namestr(std::string("name"));
+ nameref.set(nameref, (level0::ref)namestr);
+ conceptsByName.emplace(namestr, nameref.l0());
+ }
+ } namestruct;
+ return namestruct;
+}
+
+level0::ref getnamed(std::string const & name)
+{
+ auto & ns = namestruct();
+ auto res = ns.conceptsByName.find(name);
+ if (res != ns.conceptsByName.end()) {
+ return res->second;
+ } else {
+ level0::ref con = level0::alloc();
+ level0::vref namestr(name);
+ ns.conceptsByName.emplace(namestr, con);
+ con.set(ns.nameref.l0(), namestr);
+ return con;
+ }
+}
+
+ref::ref(std::string const & name)
+: ref0((level0::concept*)getnamed(name))
+{ }
+
+vref<std::string> ref::name() const
+{
+ try {
+ return vget<std::string>(namestruct().nameref);
+ } catch(level0::no_such_link_type&) {
+ return ref("UNNAMED").name();
+ }
+}
+
+bool ref::isa(ref group) const
+{
+ for (auto & g : getAll(is)) {
+ if (g == group) return true;
+ if (g == self) continue;
+ if (g.isa(group)) return true;
+ }
+ return false;
+}
+
+std::string ref::dump(ref skipmarkertype, ref skipmarkertarget)
+{
+ if (linked(skipmarkertype, skipmarkertarget)) {
+ return {};
+ }
+ std::string ret;
+ for (auto & link : links()) {
+ if (link.first == namestruct().nameref) { continue; }
+ if (ret.size() == 0) {
+ ret = name().val() + ":\n";
+ }
+ ret += " " + link.first.name().val() + ": " + link.second.name().val() + "\n";
+ }
+ link(skipmarkertype, skipmarkertarget);
+ for (auto & link : links()) {
+ if (link.first == skipmarkertype && link.second == skipmarkertarget) {
+ continue;
+ }
+ ret += link.second.dump(skipmarkertype, skipmarkertarget);
+ }
+ return ret;
+}
diff --git a/starts/meaning-vm/level-1/ref.hpp b/starts/meaning-vm/level-1/ref.hpp
new file mode 100644
index 0000000..40eee20
--- /dev/null
+++ b/starts/meaning-vm/level-1/ref.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "common.hpp"
+#include "../level-0/ref.hpp"
+#include "../level-0/ref-mixin.hpp"
+
+namespace intellect {
+namespace level1 {
+
+struct ref : public level0::refmixin<ref,vref>
+{
+ ref(level0::ref const & other) : ref0(other) { }
+ ref(std::string const & name);
+ ref(const char *name) : ref(std::string(name)) { }
+ ref(bool b) : ref(b ? "true" : "false") { }
+ ref() : ref("nothing") { }
+
+ bool isa(ref group) const;
+ bool isan(ref group) const { return isa(group); }
+
+ vref<std::string> name() const;
+
+ level0::ref & l0() { return ref0; }
+ ref & l1() { return self; }
+ ref const & l1() const { return self; }
+
+ std::string dump(ref skipmarkertype, ref skipmarkertarget);
+private:
+
+ level0::ref ref0;
+};
+
+}
+}
diff --git a/starts/meaning-vm/level-1/sugar.cpp b/starts/meaning-vm/level-1/sugar.cpp
new file mode 100644
index 0000000..eeb2eb0
--- /dev/null
+++ b/starts/meaning-vm/level-1/sugar.cpp
@@ -0,0 +1,41 @@
+#include "sugar.hpp"
+
+#include "concepts.hpp"
+
+using namespace intellect::level1;
+using namespace concepts;
+
+namespace intellect {
+namespace level1 {
+
+ref operator-(ref a, ref b)
+{
+ return ref(a.name() + "-" + b.name());
+}
+
+ref a(ref group)
+{
+ static unsigned long long gid = 0;
+ ref ret(group.name() + "-" + std::to_string(gid++));
+ ret.link(is, group);
+ ret.link(is, anonymous);
+ return ret;
+}
+ref a(ref group, ref name)
+{
+ if (!name.isa(group)) {
+ name.link(is, group);
+ }
+ return name;
+}
+ref an(ref group)
+{
+ return a(group);
+}
+ref an(ref group, ref name)
+{
+ return a(group, name);
+}
+
+}
+}
diff --git a/starts/meaning-vm/level-1/sugar.hpp b/starts/meaning-vm/level-1/sugar.hpp
new file mode 100644
index 0000000..c2fa4f9
--- /dev/null
+++ b/starts/meaning-vm/level-1/sugar.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "common.hpp"
+#include "ref.hpp"
+#include "vref.hpp"
+
+#include <string>
+#include <sstream>
+
+namespace intellect {
+namespace level1 {
+
+inline std::string operator+(vref<std::string> a, char const * b) { return std::string(a) + b; }
+inline std::string operator+(vref<std::string> a, std::string b) { return std::string(a) + b; }
+inline std::string operator+(char const * a, vref<std::string> b) { return a + std::string(b); }
+inline std::string operator+(std::string a, vref<std::string> b) { return a + std::string(b); }
+
+namespace internal {
+ template <typename... T>
+ void init_ref_names(std::string names, T &... refrefs)
+ {
+ std::stringstream ss(names);
+ ref* refptrs[] = {&refrefs...};
+ for (std::size_t i = 0; i < sizeof...(refrefs); ++ i) {
+ std::string name;
+ ss >> name;
+ if (name[name.size() - 1] == ',') {
+ name = name.substr(0, name.size() - 1);
+ }
+ refptrs[i]->l0() = ref(name).l0();
+ }
+ }
+}
+
+#define decl(...) \
+ intellect::level1::ref __VA_ARGS__; \
+ intellect::level1::internal::init_ref_names(#__VA_ARGS__, __VA_ARGS__)
+
+ref operator-(ref a, ref b);
+
+ref a(ref group);
+ref an(ref group);
+ref a(ref group, ref name);
+ref an(ref group, ref name);
+
+}
+}
diff --git a/starts/meaning-vm/level-1/vref.hpp b/starts/meaning-vm/level-1/vref.hpp
new file mode 100644
index 0000000..fb7ba5d
--- /dev/null
+++ b/starts/meaning-vm/level-1/vref.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "../level-0/vref.hpp"
+#include "ref.hpp"
+
+#include <sstream>
+
+namespace intellect {
+namespace level1 {
+
+template <typename T>
+struct vref : public level0::vref<T>
+{
+ vref(level0::vref<T> other) : level0::vref<T>((level0::concept*)other.ref) { }
+ vref(level0::value<T> *p) : level0::vref<T>(p) { }
+ vref(ref const & other) : level0::vref<T>(other) { }
+ vref(T const & val)
+ : level0::vref<T>(val)
+ {
+ std::stringstream ss;
+ ss << "v:" << val;
+ ref(self).set(ref("name"), (level0::ref)level0::vref<std::string>(ss.str()));
+ }
+
+ using level0::vref<T>::operator->;
+ using level0::vref<T>::operator T const &;
+
+ vref<std::string> name()
+ {
+ return ref(self).name();
+ }
+
+ operator ref() { return level0::ref(level0::vref<T>::ptr); }
+};
+
+
+}
+}
diff --git a/starts/meaning-vm/level1.cpp b/starts/meaning-vm/level1.cpp
new file mode 100644
index 0000000..2e7833c
--- /dev/null
+++ b/starts/meaning-vm/level1.cpp
@@ -0,0 +1,39 @@
+#include "level-1/level-1.hpp"
+
+#include <iostream>
+
+using namespace intellect::level1;
+using namespace concepts;
+
+int main()
+{
+ decl(make, linked, habit);
+ decl(needs, assumes, makes);
+ decl(not, topic);
+ decl(A, B, C);
+ decl(source, type, target);
+
+ (make-linked).set(is, habit);
+ (make-linked).set(needs, []() -> ref {
+ decl(structure, function, argument, position);
+ decl(variable, A, B, C, provide);
+
+ ref ret = a(structure);
+ ret.link(is, function-argument);
+ ret.set(argument-position, vref<int>(1)),
+ ret.set(a(variable, A), provide);
+ ret.set(a(variable, B), provide);
+ ret.set(a(variable, C), provide);
+ return ret;
+ }());
+ a(link, A-B-C-linked).set(link-source, A);
+ (A-B-C-linked).set(link-type, B);
+ (A-B-C-linked).set(link-target, C);
+ a(not, not-A-B-C-linked).set(topic, A-B-C-linked);
+ (make-linked).set(assumes, not-A-B-C-linked);
+ (make-linked).set(makes, A-B-C-linked);
+
+ std::cout << (make-linked).dump("dumped", true) << std::endl;
+
+ return 0;
+}
diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile
index 748cca2..d08f0b1 100644
--- a/starts/meaning-vm/makefile
+++ b/starts/meaning-vm/makefile
@@ -1,8 +1,11 @@
CXXFLAGS=-Wall -Werror -std=c++17 -fno-operator-names -ggdb -O0
LINK.o=$(LINK.cc)
+all: level0 level1
level0: level0.o liblevel0.a
liblevel0.a: level-0/memorystore.o level-0/concept.o level-0/ref.o
+level1: level1.o liblevel0.a liblevel1.a
+liblevel1.a: level-1/ref.o level-1/sugar.o level-1/concepts.o
%.a:
ar ru $@ $^
ranlib $@
@@ -10,4 +13,4 @@ liblevel0.a: level-0/memorystore.o level-0/concept.o level-0/ref.o
main: main.o concept.o helpers.o memorystore.o meaning.o
*.o: *.hpp */*.hpp
clean:
- -rm *.o main level0 *.a */*.o
+ -rm *.o main level0 level1 level2 *.a */*.o