diff options
Diffstat (limited to 'starts/meaning-vm')
-rw-r--r-- | starts/meaning-vm/concept.cpp | 14 | ||||
-rw-r--r-- | starts/meaning-vm/concept.hpp | 1 | ||||
-rw-r--r-- | starts/meaning-vm/helpers.cpp | 44 | ||||
-rw-r--r-- | starts/meaning-vm/helpers.hpp | 2 | ||||
-rw-r--r-- | starts/meaning-vm/main.cpp | 24 |
5 files changed, 61 insertions, 24 deletions
diff --git a/starts/meaning-vm/concept.cpp b/starts/meaning-vm/concept.cpp index c46b058..c064ed4 100644 --- a/starts/meaning-vm/concept.cpp +++ b/starts/meaning-vm/concept.cpp @@ -58,3 +58,17 @@ void concept::unlink(ref type, ref target) } throw std::out_of_range("no such concept link to erase"); } + +void concept::unlink(ref type) +{ + auto ls = links.equal_range(type.ptr); + if (ls.first == ls.second) { + throw std::out_of_range("no such concept link to erase"); + } + auto mid = ls.first; + ++ mid; + if (mid != ls.second) { + throw std::out_of_range("more than one link of type to erase"); + } + links.erase(ls.first); +} diff --git a/starts/meaning-vm/concept.hpp b/starts/meaning-vm/concept.hpp index 4d73770..e5cddec 100644 --- a/starts/meaning-vm/concept.hpp +++ b/starts/meaning-vm/concept.hpp @@ -66,6 +66,7 @@ struct concept array getAll(ref type); void link(ref type, ref target); void unlink(ref type, ref target); + void unlink(ref type); }; template <typename T> diff --git a/starts/meaning-vm/helpers.cpp b/starts/meaning-vm/helpers.cpp index 8c8618d..dae149f 100644 --- a/starts/meaning-vm/helpers.cpp +++ b/starts/meaning-vm/helpers.cpp @@ -9,16 +9,38 @@ ref operator-(ref a, ref b) return ref(a.name() + "-" + b.name()); } -ref ref::operator=(ref other) +ref ref::operator=(ref that) { - // if this is not anonymous, and other is, then we are naming it - /*declrefs(anonymous); - if (other->linked(anonymous, true) && !ptr->linked(anonymous, true)) { - return; - }*/ + // if this is not anonymous, and that is, then we are naming it + declrefs(anonymous, name, is); + if (that->linked(anonymous, true) && !ptr->linked(anonymous, true)) { + // this is assignment of anonymous content to empty named concept + bool donealready = false; + if (ptr->links.size() != 1) { + // if we have links, and that has links we do not have, an error has been made + for (auto & link : that->links) { + if (ref(link.first) == anonymous) { continue; } + if (ref(link.first) == name) { continue; } + if (!ptr->linked(ref(link.first), ref(link.second))) { + throw std::logic_error(this->name() + " already defined otherwise from " + that->get(is).name()); + } + } + donealready = true; + } + that->unlink(anonymous, true); + auto nam = that->get(name); + that->unlink(name, nam); + dealloc(nam); + if (!donealready) { + ptr->links.insert(that->links.begin(), that->links.end()); + } + dealloc(that); + return *this; + } + // if this is link-type, make new concept [not checked, might want to assume] ref ret = alloc(); - ret->link(*this, other); + ret->link(*this, that); return ret; } @@ -81,10 +103,18 @@ ref a(ref what) declrefs(is, anonymous); return ref(what.name() + "-" + std::to_string(gid++))[is = what, anonymous = true]; } +ref a(ref what, ref name) +{ + return name = a(what); +} ref an(ref what) { return a(what); } +ref an(ref what, ref name) +{ + return a(what, name); +} bool ref::isa(ref what) const { diff --git a/starts/meaning-vm/helpers.hpp b/starts/meaning-vm/helpers.hpp index 103e826..eca2479 100644 --- a/starts/meaning-vm/helpers.hpp +++ b/starts/meaning-vm/helpers.hpp @@ -53,3 +53,5 @@ ref operator-(ref a, ref b); ref a(ref what); ref an(ref what); +ref a(ref what, ref name); +ref an(ref what, ref name); diff --git a/starts/meaning-vm/main.cpp b/starts/meaning-vm/main.cpp index f8e4ec0..c4207cb 100644 --- a/starts/meaning-vm/main.cpp +++ b/starts/meaning-vm/main.cpp @@ -35,28 +35,18 @@ int main() declrefs(trueness, truth, what, not); declrefs(add, unique, habit, needs, assumes, makes); - A[is = variable]; - B[is = variable]; - C[is = variable]; + A = a(variable); + B = a(variable); + C = a(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. - - // would like to do A = a(variable); - // solution might be to tag anons as such, and take them with a condition in operator= - // since we want to return a ref, change [is=variable] to use refs. this means learning - // to delete them, which means checking if they are used or not. - // where do we put the deleting? - // right now helpers is doing memory. maybe instead we can have a memory class. - // ideally memory is handled by a concept. - // let's make a pool of concepts? - (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] + add-link-unique = a(habit)[ + needs = a(variable, A), needs = a(variable, B), needs = a(variable, C), + makes = a(link, abc-linked)[link-source = A, link-type = B, link-target = C], + assumes = a(trueness, abc-not-linked)[what = abc-linked, truth = false] ]; dumpconcept(add-link-unique); |