From cd03e291664cb102bde61d86a15f0add11809766 Mon Sep 17 00:00:00 2001 From: olpc user Date: Sun, 24 Nov 2019 19:23:37 -0800 Subject: messy but works. rushing to get this done with may have been a poor investment. --- starts/meaning-vm/DESIGN.txt | 6 ++ starts/meaning-vm/level-0/concept.cpp | 6 +- starts/meaning-vm/level-0/level-0.hpp | 1 - starts/meaning-vm/level-0/memorystore.cpp | 6 +- starts/meaning-vm/level-0/ref-mixin.hpp | 27 ++++++--- starts/meaning-vm/level-0/ref.cpp | 4 +- starts/meaning-vm/level-0/ref.hpp | 13 +++-- starts/meaning-vm/level-0/vref.hpp | 3 +- starts/meaning-vm/level-1/common.hpp | 10 ++++ starts/meaning-vm/level-1/concepts.cpp | 13 +++++ starts/meaning-vm/level-1/concepts.hpp | 20 +++++++ starts/meaning-vm/level-1/level-1.hpp | 7 +++ starts/meaning-vm/level-1/ref.cpp | 91 +++++++++++++++++++++++++++++++ starts/meaning-vm/level-1/ref.hpp | 34 ++++++++++++ starts/meaning-vm/level-1/sugar.cpp | 41 ++++++++++++++ starts/meaning-vm/level-1/sugar.hpp | 47 ++++++++++++++++ starts/meaning-vm/level-1/vref.hpp | 38 +++++++++++++ starts/meaning-vm/level1.cpp | 39 +++++++++++++ starts/meaning-vm/makefile | 5 +- 19 files changed, 386 insertions(+), 25 deletions(-) create mode 100644 starts/meaning-vm/level-1/common.hpp create mode 100644 starts/meaning-vm/level-1/concepts.cpp create mode 100644 starts/meaning-vm/level-1/concepts.hpp create mode 100644 starts/meaning-vm/level-1/level-1.hpp create mode 100644 starts/meaning-vm/level-1/ref.cpp create mode 100644 starts/meaning-vm/level-1/ref.hpp create mode 100644 starts/meaning-vm/level-1/sugar.cpp create mode 100644 starts/meaning-vm/level-1/sugar.hpp create mode 100644 starts/meaning-vm/level-1/vref.hpp create mode 100644 starts/meaning-vm/level1.cpp (limited to 'starts') 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 #include namespace intellect { @@ -7,25 +8,33 @@ namespace level0 { template typename vref> struct refmixin { + using links_t = std::multimap; using array = std::vector; - 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(type), conv(target)); } + void unlink(ref const & type, ref const & target) { p()->unlink(conv(type), conv(target)); } + void unlink(ref const & type) { p()->unlink(conv(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(type)); } + bool linked(ref const & type, ref const & target) const { return p()->linked(conv(type), conv(target)); } - array getAll(ref const & type) const { return conv(ptr()->getAll(type)); } + array getAll(ref const & type) const { return conv(p()->getAll(conv(type))); } - ref get(ref const & type) const { return conv(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(p()->get(conv(type))); } + void set(ref const & type, ref const & target) { p()->set(conv(type), conv(target)); } template vref vget(ref const & type) const { return conv>(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(this)->ptr; } + inline concept * p() const { return *conv(this); } + using r = level0::ref; template 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(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(val))) { } - vref(ref const & other) : ptr(static_cast*>(other.ptr)) { } + vref(ref const & other) : ptr(static_cast*>((concept*)other)) { } operator ref() { return ptr; } T const & val() { return *ptr; } // for use by containers bool operator<(vref const & other) const { return self.ptr < other.ptr; } +protected: value * 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 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 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 + +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::ref,std::hash,std::equal_to> 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 ref::name() const +{ + try { + return vget(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(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 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 +#include + +namespace intellect { +namespace level1 { + +inline std::string operator+(vref a, char const * b) { return std::string(a) + b; } +inline std::string operator+(vref a, std::string b) { return std::string(a) + b; } +inline std::string operator+(char const * a, vref b) { return a + std::string(b); } +inline std::string operator+(std::string a, vref b) { return a + std::string(b); } + +namespace internal { + template + 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 + +namespace intellect { +namespace level1 { + +template +struct vref : public level0::vref +{ + vref(level0::vref other) : level0::vref((level0::concept*)other.ref) { } + vref(level0::value *p) : level0::vref(p) { } + vref(ref const & other) : level0::vref(other) { } + vref(T const & val) + : level0::vref(val) + { + std::stringstream ss; + ss << "v:" << val; + ref(self).set(ref("name"), (level0::ref)level0::vref(ss.str())); + } + + using level0::vref::operator->; + using level0::vref::operator T const &; + + vref name() + { + return ref(self).name(); + } + + operator ref() { return level0::ref(level0::vref::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 + +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(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 -- cgit v1.2.3