From 94ed7bbaa739995a9815b5f1c916d9e24575368c Mon Sep 17 00:00:00 2001 From: olpc user Date: Thu, 26 Dec 2019 16:34:28 -0800 Subject: level2 compiles, nothing visible yet --- starts/meaning-vm/habit-starts/rhythm.cpp | 2 +- starts/meaning-vm/level-2/habits.cpp | 70 +++++++++---- starts/meaning-vm/level-2/habits.hpp | 159 ++++++++++++++++++++++++++++++ starts/meaning-vm/level-2/sugar.cpp | 32 ++++++ starts/meaning-vm/level-2/sugar.hpp | 26 ++--- starts/meaning-vm/level2.cpp | 45 +++++++++ starts/meaning-vm/makefile | 4 +- 7 files changed, 301 insertions(+), 37 deletions(-) create mode 100644 starts/meaning-vm/level-2/sugar.cpp diff --git a/starts/meaning-vm/habit-starts/rhythm.cpp b/starts/meaning-vm/habit-starts/rhythm.cpp index 72626d6..01a42d9 100644 --- a/starts/meaning-vm/habit-starts/rhythm.cpp +++ b/starts/meaning-vm/habit-starts/rhythm.cpp @@ -119,7 +119,7 @@ int main() #endif ahabit(wait-habit, (), { - usleep(micros); + sugar::usleep(micros); }); (keep-doing-habit)(start-beat); diff --git a/starts/meaning-vm/level-2/habits.cpp b/starts/meaning-vm/level-2/habits.cpp index 4900daf..266d412 100644 --- a/starts/meaning-vm/level-2/habits.cpp +++ b/starts/meaning-vm/level-2/habits.cpp @@ -13,6 +13,16 @@ int createhabits() s.link(t, dst); }); + ahabit(link-crucial, ((souce, s), (type, t), (target, dst)), + { + result = s.crucial(t, dst); + }); + + ahabit(link-set-crucial, ((source, s), (type, t), (target, dst)), + { + s.setcrucial(t, dst); + }); + decls(linked, anything); ahabit(linked, ((source, s), (type, t), (target, dst, anything)), { @@ -66,6 +76,14 @@ int createhabits() { intellect::level0::basic_dealloc(c); }); + ahabit(concept-crucial, ((concept, c)), + { + result = c.crucial(); + }); + ahabit(concept-set-crucial, ((concept, c)), + { + c.setcrucial(); + }); decls(habit, context); ahabit(know-is, ((concept, c), (group, g)), @@ -138,6 +156,20 @@ int createhabits() { return lea.val() == leb.val(); }); + ahabit(link-entry-unlink, ((link-entry, le)), + { + le.get(source).unlink(le.val()++); + (populate-link-entry)(le); + result = le; + }); + ahabit(link-entry-crucial, ((link-entry, le)), + { + result = le.get(source).crucial(le.val()); + }); + ahabit(link-entry-set-crucial, ((link-entry, le)), + { + le.get(source).setcrucial(le.val()); + }); // a simple list primitive to aid in dev decls(list, nothing, next, previous, first, last, act); @@ -185,6 +217,8 @@ int createhabits() l.set(last-item, le); prev.set(next, le); } + + result = list; }); ahabit(list-entry-unmake, ((list-entry, le)), { @@ -197,15 +231,19 @@ int createhabits() set(n, previous, prev); } (concept-unmake)(le); + result = n; }); - ahabit(list-each-entry, ((list, l), (context, c), (action, act)), - { - ref cur = (list-first-entry)(l); - while (cur != nothing && result == nothing) { - result = act(cur, c); - cur = (list-next-entry)(cur); + ahabit(list-each-entry, ((list, l), (context, c), (action, a)), + { + ref subctx = (make-concept()); + subctx.set(context, c); + subctx.set(list-entry, (list-first-entry)(l)); + while (subctx.get(list-entry) != nothing && result == nothing) { + result = act(a, subctx); + subctx.set(list-entry, (list-entry-next)(subctx.get(list-entry))); } + (unmake-concept)(subctx); }); ahabit(list-has-item, ((list, l), (item, i)), { @@ -260,6 +298,7 @@ int createhabits() { if (linked(act, is, habit) && !linked(act, habit)) { act.fun()(subctx); + result = subctx.get("result"); } else if (linked(act, habit) && linked(get(act, habit), is, habit)) { ref h = get(act, habit); if (linked(h, habit)) { @@ -275,9 +314,10 @@ int createhabits() "action", act ); self(h, subctx2); + result = subctx2.get("result"); (unmake-concept)(subctx2); } else { - h({{context, subctx}, {action, act}}); + result = h({{context, subctx}, {action, act}}); } } else { throw (make-concept)().link( @@ -297,7 +337,7 @@ int createhabits() made-information-map, out, action, act); }); - ahabit(context-action, ((outer-context, outerctx), (context-action, ca)), + ahabit(context-action, ((context, outerctx), (action, ca)), { ref action = ca["action"]; @@ -339,24 +379,12 @@ int createhabits() (action-list-item)(list-entry-item(le), subctx); }); - // maybe condition and list could be merged better by factoring out the concept - // of translating? - // we're going to want to provide lists of subactions to condition - // the irritation around not having the condition be a function is the - // creation of anonymous variable names to hold the values. is likely fine. - // note: the name "outer-context" is being treated specially. we'll just use that. - // this name could make a quoting requirement. could be worked around. - // - // if we remove outer-context, we'll probably need to recognize condition- - // action in action-list-item, and pass the outer-context to it. - // either way, we can implement condition-action with outer-context as - // a passed value. - ahabit(nothing, (), {}); link(nothing, habit, nothing); // does acts[cond] in outer-context. // uses acts[anything] if there is no acts[cond]. + ahabit(condition-action, ((condition, cond), (actions, acts)), { ref outerctx = linked(ctx, "outer-context") ? ctx["outer-context"] : ctx; diff --git a/starts/meaning-vm/level-2/habits.hpp b/starts/meaning-vm/level-2/habits.hpp index 0bff7f7..b416ee0 100644 --- a/starts/meaning-vm/level-2/habits.hpp +++ b/starts/meaning-vm/level-2/habits.hpp @@ -1,10 +1,169 @@ +#pragma once + #include "common.hpp" +#include "ref.hpp" +#include "concepts.hpp" namespace intellect { namespace level2 { void ensurehabitscreated(); // for running from static code, for construction order +namespace concepts { + + // make a link + // link(source, type, target) + static ref link("link"); + + // get if a link is permanent + // result = (link-crucial)(source, type, target) + static ref crucial("crucial"); + + // set a link to be permanent + // (link-set-crucial)(source, type, target) + static ref set("set"); + + // get if a link exists + // result = linked(source, type, target? = anything) + static ref linked("linked"); + + // remove a link + // unlink(source, type, target) + static ref unlink("unlink"); + + // get a link target by type + // result = get(source, type) + static ref get("get"); + + // set a link target, replacing an existing type if needed + // set(source, type, target) + + // produce a totally new, empty concept, with no links to or from + // result = (make-concept)() + static ref make("make"), concept("concept"); + + // produce a new concept by copying links and data from an old concept. + // nothing will link to new concept. + // result = (make-copy)(concept) + static ref copy("copy"); + + // destroy a concept forever, for handling temporary data. + // this will fail if the concept is set to be crucial, or is in use. + // (concept-unmake)(concept) + static ref unmake("unmake"); + + // get if a concept is set to be crucial + // result = (concept-crucial)(concept) + + // set a concept to be crucial + // r(concept-set-crucial)(concept) + + // place a concept in a new group. + // forms a new link of type 'is', fails if one aleady exists + // concept = (know-is)(concept, group) + static ref know("know"), is("is") ; + + // fill any concept with information about the first link entry in a concept + // if there is a link in the entry, then [type] and [target] will be present + // link-entry = (know-is-first-link-entry)(link-entry, concept) + static ref first("first"), entry("entry"); + + // fill any concept with information about the last link entry in a concept + // link-entry = (know-is-last-link-entry)(link-entry, concept) + static ref last("last"); + + // change a link entry concept to be about the next link in the concept + // link-entry = (next-link-entry)(link-entry) + + // change a link entry concept to be about the previous link in the concept + // link-entry = (previous-link-entry)(link-entry) + static ref previous("previous"); + + // get if two link entry concepts refer to the same link entry + // result = (same-link-entry)(link-entry-A, link-entry-B) + static ref same("same"); + + // remove a link entry from a concept + // the entry will be about the next one, after the action + // link-entry = (link-entry-unlink)(link-entry) + + // get if a link entry is set to be crucial + // result = (link-entry-crucial)(link-entry) + + // set a link entry to be crucial & permanent + // (link-entry-set-crucial)(link-entry) + + // add links to a concept facilitating use as a list + // list = (know-is-list)(list) + static ref list("list"); + + // get the first list-entry of a list + // result = (list-first-entry)(list) + + // get the last list-entry of a list + // result = (list-last-entry)(list) + + // get a subsequent list-entry + // result = (list-entry-next)(list-entry) + + // get a preceding list-entry + // result = (list-entry-previous)(list-entry) + + // get the item associated with a list-entry + // result = (list-entry-item)(list-entry) + static ref item("item"); + + // make a new entry in a list, holding an item concept + // list = (make-next-list-entry)(list, item) + + // destroy forever an entry in a list. for lists of temporaries. + // the result is the next entry. + // result = (list-entry-unmake)(list-entry, le) + + // action(list-entry, context) for every entry in a list until result made + // result = (list-each-entry)(list, context, action) + static ref each("each"); + + // get if a list has an item in it + // result = (list-has-item)(list, item) + static ref has("has"); + + // destroy forever an entry in its list, by the item it contains + // for lists of temporaries + // true = (list-item-entry-unmake)(list, item) + + // the .act level-2 member function can ease list creation. + // it passes itself as the first argument to a habit + // (make-concept)().act(know-is-list) + // .act(make-next-list-entry, i1) + // .act(make-next-list-entry, i2) + // ...; + + // make a concept holding an item in a translation map + // result = (make-map-item)(source, target) + static ref map("map"); + + // make a contextual subcontext for an action + // the maps are lists of translation map items + // result = (make-context-action)(needed-information-map, made-information-map, action) + static ref action("action"); + + // condition do one of multiple possible actions + // looks up actions[condition] and does that. + // does actions[anything] if nothing matches. + // result = (condition-action)(condition, actions) + static ref condition("condition"); + + // action handlers + // calls anything with a 'habit' handler: act(action, context) + // for action is habit: provides context as full context + // for action has habit: calls habit with unordered (context, action) + // recursively handles if habit itself has habit to handle it. + // the habit of habits, calls a habit: habit(context, action) + // the habit of context-actions, calls a subcontextual action: (context-action)(context, action) + // the habit of action lists, calls a list of actions: (action-list)(context, action) + // the habit of 'nothing', does nothing: (nothing)() +} } } diff --git a/starts/meaning-vm/level-2/sugar.cpp b/starts/meaning-vm/level-2/sugar.cpp new file mode 100644 index 0000000..2a86cca --- /dev/null +++ b/starts/meaning-vm/level-2/sugar.cpp @@ -0,0 +1,32 @@ +#include "sugar.hpp" + +#include // int rand(); void srand(int seed); +#include // int time(0); int clock_gettime(CLOCK_REALTIME, struct timespec *tp{tv_sec,tv_nsec}) +#include // usleep(unsigned int usecs) + +namespace intellect { +namespace level2 { +namespace sugar { + +double rand(double min, double max) +{ + // seed random number generator statically, for habit delay + static struct timespec tp; + static int seed = ( + clock_gettime(CLOCK_REALTIME, &tp), + srand(tp.tv_nsec), + tp.tv_nsec + ); + (void)(seed); + + return double(::rand()) / RAND_MAX * (max - min) + min; +} + +void usleep(unsigned int usecs) +{ + ::usleep(usecs); +} + +} +} +} diff --git a/starts/meaning-vm/level-2/sugar.hpp b/starts/meaning-vm/level-2/sugar.hpp index adedaa9..04393a1 100644 --- a/starts/meaning-vm/level-2/sugar.hpp +++ b/starts/meaning-vm/level-2/sugar.hpp @@ -1,11 +1,15 @@ #pragma once -#include // int rand(); void srand(int seed); -#include // int time(0); int clock_gettime(CLOCK_REALTIME, struct timespec *tp{tv_sec,tv_nsec}) -#include // usleep(unsigned int usecs) - #undef self +namespace intellect { +namespace level2 { + +namespace sugar { + void usleep(unsigned int usecs); + double rand(double min, double max); +} + // habits have a structure such that they contain information about their positional // arguments. they are made with a macro that turns the args into local variables. // the function to call them takes any number of arguments, and these are placed in the @@ -28,8 +32,8 @@ [&](ref ctx) \ { \ { \ - static int delay = (double(rand()) / RAND_MAX * 400000 + 200000); \ - usleep(delay); \ + static int delay = sugar::rand(200000, 400000); \ + sugar::usleep(delay); \ } \ ref self = ref(#name); (void)self; \ ref result("nothing"); (void)result; \ @@ -55,10 +59,6 @@ ref tok = ctx.linked(ref(#name)) ? ctx[ref(#name)] : ref(#__VA_ARGS__); #define _macro_habit_assume(info, tok, ...) \ if ((#__VA_ARGS__)[0] != 0) { intellect::level2::habitassume(_macro_habit_name, ref(#info), ref(#__VA_ARGS__)); } - - // seed random number generator statically, for habit delay - namespace _macro_habit { - static struct timespec tp; - static int timeres = clock_gettime(CLOCK_REALTIME, &tp); - static int seed = (srand(tp.tv_nsec), tp.tv_nsec); - } + +} +} diff --git a/starts/meaning-vm/level2.cpp b/starts/meaning-vm/level2.cpp index c04a5cc..ebdf121 100644 --- a/starts/meaning-vm/level2.cpp +++ b/starts/meaning-vm/level2.cpp @@ -1,9 +1,54 @@ #include "level-2/level-2.hpp" +#include "level-1/level-1.hpp" #include +#include using namespace intellect::level2; +using namespace intellect::level2::concepts; int main() { + decls(dump, name, of, is, nothing); + ahabit(name-of, ((concept, c)), + { + if (linked(c, name)) { + result = get(c, name); + } else { + for (auto & group : c.getAll(is)) { + result = (name-of)(group); + if (result != nothing) { break; } + } + std::stringstream ss; + if (result != nothing) { + ss << result.val(); + } else { + ss << "unnamed"; + } + ss << "-" << std::hex << (size_t)(c.ptr()); + intellect::level1::givename(c, ss.str()); + result = get(c, name); + } + }); + // I guess I'd better code dump as a behavior. + ahabit(dump, ((concept, c)), + { + decls(type, target); + static std::set dumped; + if (dumped.count(c) == 0) { + std::cout << (name-of)(c).val() << ":" << std::endl; + dumped.insert(c); + ref le = (make-concept)().act(know-is-first-link-entry, c); + while (le.linked(target)) { + std::cout << " " << (name-of)(le.get(type)).val() << ": " << (name-of)(le.get(target)).val() << std::endl; + (next-link-entry)(le); + } + (know-is-first-link-entry)(le, c); + while (le.linked(target)) { + (dump)(le.get(target)); + (next-link-entry)(le); + } + (unmake-concept)(le); + } + }); } diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile index 0a9738c..b2df672 100644 --- a/starts/meaning-vm/makefile +++ b/starts/meaning-vm/makefile @@ -3,12 +3,12 @@ CXXFLAGS=-pedantic -Wall -Werror -Wno-error=deprecated-declarations -Wno-gnu-zero-variadic-macro-arguments -std=gnu++17 -fno-operator-names -ggdb -O0 LINK.o=$(LINK.cc) -all: level0 level1 habit-starts/rhythm +all: level0 level1 habit-starts/rhythm level2 level0: level0.o liblevel0.a liblevel0.a: $(patsubst %.cpp,%.o,$(wildcard level-0/*.cpp)) level1: level1.o liblevel1.a liblevel1.a: $(patsubst %.cpp,%.o,$(wildcard level-0/*.cpp)) $(patsubst %.cpp,%.o,$(wildcard level-1/*.cpp)) -level2: liblevel2.a +level2: level2.o liblevel2.a liblevel2.a: $(patsubst %.cpp,%.o,$(wildcard level-0/*.cpp)) $(patsubst %.cpp,%.o,$(wildcard level-1/*.cpp)) $(patsubst %.cpp,%.o,$(wildcard level-2/*.cpp)) habit-starts/rhythm: habit-starts/rhythm.o liblevel2.a -- cgit v1.2.3