diff options
-rw-r--r-- | starts/meaning-vm/concept.cpp | 15 | ||||
-rw-r--r-- | starts/meaning-vm/concept.hpp | 9 | ||||
-rw-r--r-- | starts/meaning-vm/helpers.cpp | 55 | ||||
-rw-r--r-- | starts/meaning-vm/helpers.hpp | 35 | ||||
-rw-r--r-- | starts/meaning-vm/main.cpp | 43 | ||||
-rw-r--r-- | starts/meaning-vm/makefile | 2 |
6 files changed, 151 insertions, 8 deletions
diff --git a/starts/meaning-vm/concept.cpp b/starts/meaning-vm/concept.cpp index dc9ecca..58d1a7c 100644 --- a/starts/meaning-vm/concept.cpp +++ b/starts/meaning-vm/concept.cpp @@ -5,6 +5,21 @@ ref concept::id() return this; } +bool concept::linked(ref type) +{ + return links.count(type) > 0; +} + +bool concept::linked(ref type, ref target) +{ + for (ref t : getAll(type)) { + if (t == target) { + return true; + } + } + return false; +} + ref concept::get(ref type) { auto result = links.equal_range(type); diff --git a/starts/meaning-vm/concept.hpp b/starts/meaning-vm/concept.hpp index a80b157..2b05f44 100644 --- a/starts/meaning-vm/concept.hpp +++ b/starts/meaning-vm/concept.hpp @@ -19,10 +19,17 @@ struct ref // for helpers ref(std::string const &); ref(char const * str) : ref(std::string(str)) { } + ref(bool b) : ref(b ? "true" : "false") { } ref() : ref("nothing") { } value<std::string> & name() const; operator const char *() const; + concept operator=(ref other); // helper constructs new concept with this as link + ref operator[](concept links); // helper sets all links from passed concept + + bool isa(ref what) const; + bool isan(ref what) const; + concept * ptr; }; @@ -33,6 +40,8 @@ struct concept using array = std::vector<ref>; ref id(); + bool linked(ref type); + bool linked(ref type, ref target); ref get(ref type); // returns first array getAll(ref type); void link(ref type, ref target); diff --git a/starts/meaning-vm/helpers.cpp b/starts/meaning-vm/helpers.cpp index fb17f6c..99c83dd 100644 --- a/starts/meaning-vm/helpers.cpp +++ b/starts/meaning-vm/helpers.cpp @@ -2,10 +2,35 @@ #include <unordered_map> -// these concept names are for bootstrapping convenience, +ref operator-(ref a, ref b) +{ + return ref(a.name() + "-" + b.name()); +} + +concept ref::operator=(ref other) +{ + // if this is link-type, make new concept + concept ret; + ret.link(*this, other); + return ret; +} + +ref ref::operator[](concept links) { + ptr->links.insert(links.links.begin(), links.links.end()); + return *this; +} + +concept operator,(concept a, concept b) +{ + concept ret; + ret.links.insert(a.links.begin(), a.links.end()); + ret.links.insert(b.links.begin(), b.links.end()); + return ret; +} + +// concept names are for bootstrapping convenience, // to make hardcoding structures easier. // hence there is just one single list of them - concept namesByConcept; std::unordered_map<value<std::string>,concept,std::hash<std::string>> conceptsByName; @@ -30,3 +55,29 @@ value<std::string> & ref::name() const ref::operator const char *() const { return name().c_str(); } + +ref a(ref what) +{ + static unsigned long long gid = 0; + declrefs(is); + return ref(what.name() + "-" + std::to_string(gid++))[is = what]; +} +ref an(ref what) +{ + return a(what); +} + +bool ref::isa(ref what) const +{ + declrefs(is); + for (auto group : ptr->getAll(is)) { + if (group == what) return true; + if (group.isa(what)) return true; + } + return false; +} + +bool ref::isan(ref what) const +{ + return isa(what); +} diff --git a/starts/meaning-vm/helpers.hpp b/starts/meaning-vm/helpers.hpp index f1b9e36..d151849 100644 --- a/starts/meaning-vm/helpers.hpp +++ b/starts/meaning-vm/helpers.hpp @@ -1,7 +1,32 @@ #pragma once -#include "concept.hpp" +// Provides for syntax sugar easing hardcoding. +// 1. concept names +// use declrefs(apple, is, fruit, water, has) +// to quickly define the named ref variables, +// referring always to the same named concept. +// the ref constructor provides for using +// 'true' and 'false' as refs. +// 2. links +// links may be quickly made with +// apple[is = fruit, has = water] +// which links 'apple' by 'is' to 'fruit' +// and by 'has' to 'water' in one line +// 3. hyphenation +// refs may be hyphenated (subtracted) to +// produce a new ref with the conglomerate name +// apple-has-water.name(): "apple-has-water" +// this may be expanded upon. +// 4. anonymous concept creation +// an unnamed instance of a concept may be created with the a() or an() equivalent functions: +// ref anongreenapple = an(apple)[color = green]; +// it will be given a name such as apple-3 +// 5. quick group checking +// the obverse of the a()/an() functions is provided +// by ref::isa() and ref::isan() which quickly check +// if there is an "is" link to the passed ref. +#include "concept.hpp" #include <sstream> template <typename... T> @@ -19,6 +44,12 @@ void __helper_init_ref_names(std::string names, T &... refrefs) } } -#define decl(...) \ +#define declrefs(...) \ ref __VA_ARGS__; \ __helper_init_ref_names(#__VA_ARGS__, __VA_ARGS__) + +concept operator,(concept a, concept b); +ref operator-(ref a, ref b); + +ref a(ref what); +ref an(ref what); diff --git a/starts/meaning-vm/main.cpp b/starts/meaning-vm/main.cpp index 1392957..f9f8118 100644 --- a/starts/meaning-vm/main.cpp +++ b/starts/meaning-vm/main.cpp @@ -5,10 +5,47 @@ using namespace std; #include <iostream> +void dumpconcept(ref r) +{ + declrefs(dumped); + + for (auto & l : r->links) { + cout << r << " " << l.first << " " << l.second << endl; + } + if (!r->linked(dumped)) { + r[dumped = true]; + } + for (auto & l : r->links) { + if (!l.second->linked(dumped)) { + dumpconcept(l.second); + } + } +} + int main() { - decl(fruit, banana, is); + declrefs(is, link, type); + is->link(is, link-type); + + declrefs(source, target); + declrefs(linked, A, B, C, abc, variable); + declrefs(trueness, truth, what, not); + + declrefs(add, unique, habit, needs, assumes, makes); + A[is = variable]; + B[is = variable]; + C[is = variable]; + + // add a new unique link to a concept + // given A, B, C + // and assuming A is not linked by B to C, + // makes A be linked by B to C. + (add-link-unique)[ + is = habit, + needs = A, needs = B, needs = C, + makes = (abc-linked)[is = link, link-source = A, link-type = B, link-target = C], + assumes = (abc-not-linked)[is = trueness, what = abc-linked, truth = false] + ]; - banana->link(is, fruit); - cout << banana << "-" << is << "-" << fruit << endl; + dumpconcept(add-link-unique); } diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile index ebbb00e..a562715 100644 --- a/starts/meaning-vm/makefile +++ b/starts/meaning-vm/makefile @@ -1,4 +1,4 @@ -CXXFLAGS=-std=c++14 -ggdb +CXXFLAGS=-std=c++14 -fno-operator-names -ggdb LINK.o=$(LINK.cc) main: main.o concept.o helpers.o |