summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--starts/meaning-vm/concept.cpp15
-rw-r--r--starts/meaning-vm/concept.hpp9
-rw-r--r--starts/meaning-vm/helpers.cpp55
-rw-r--r--starts/meaning-vm/helpers.hpp35
-rw-r--r--starts/meaning-vm/main.cpp43
-rw-r--r--starts/meaning-vm/makefile2
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