summaryrefslogtreecommitdiff
path: root/starts
diff options
context:
space:
mode:
Diffstat (limited to 'starts')
-rw-r--r--starts/meaning-vm/level-2/habits.cpp140
-rw-r--r--starts/meaning-vm/level2.cpp268
2 files changed, 367 insertions, 41 deletions
diff --git a/starts/meaning-vm/level-2/habits.cpp b/starts/meaning-vm/level-2/habits.cpp
index 49a48a3..c58cc74 100644
--- a/starts/meaning-vm/level-2/habits.cpp
+++ b/starts/meaning-vm/level-2/habits.cpp
@@ -35,16 +35,49 @@ void poplinkentry(ref le)
}
}
-ref maketranslationmap(ref m, ref k = nothing)
+// translationmap seems like extra verbose thing
+// might just link to step:
+// needed-map
+// needed-set
+// made-map
+ref settranslationmap(ref c, ref m, ref k = nothing)
{
- ref result = makeconcept();
- result.link(
+ c.link(
//habit, translation-map,
"translation", m
);
- if (k != nothing) { result.link("known", k); }
- return result;
+ if (k != nothing) { c.link("known", k); }
+ return c;
}
+// we would like to use condition kind of like
+// condition.next-step[true] =
+// but provide for lots of exploration options
+// next-steps, on a condition, would be an accessor. relates to structures, and virtual methods.
+// until we have one of those 3 things, i guess,
+// we'd have to decide which underlying representation to work with.
+// i guess it seems okay to use a simpler underlying representation.
+// it means adding more data is a little weird, making for more verbose accessors later
+// there's a compromise where a little generality is added at a lower level
+// it is easier for ai to do verbosity than karl. it can automate it.
+// just code an accessor for next-steps, I guess.
+// what do we want this for?
+// want code after condition in script
+// to link to anything option
+// is just hard to access anything option
+// off-hand, karl doesn't know where it is.
+// concern around what to do if anything option is specified in script
+// throw error if also code after
+// maybe it is more intuitive to continue on after the condition.
+// this would make condition resolve to a step, kind of.
+// after the condition block, you'd want all the condition steps
+// to wire to the following step as their next one
+// means rewriting next-step for every condition, i guess
+// instantiating next step in advance
+// makes returning instead of continuing irritating
+// would need to either rewire or have a noop step
+// so, to mke choice, just rewrite for every condition
+// means accessing every condition. no need to rewrite whole structure, just look up how to access. faster than rewriting.
+// make a function to wire to end
void contextmapinto(ref c1, ref m, ref c2)
{
@@ -143,9 +176,9 @@ void _condition(ref ctx, ref cond, ref steps, ref state)
next = steps[cond];
}
- if (next != nothing) {
+ //if (next != nothing) {
state.set("next-step", next);
- }
+ //}
}
void createhabits()
@@ -209,22 +242,27 @@ void createhabits()
decls(make, unmake, know, concept, is, group, already, in, iter);
ahabit(make-concept, (), { result = makeconcept(); });
- ahabit(make-copy, ((concept, c)),
+ ahabit(copy-to, ((source, s), (target, t)),
{
// copies data too
- result = makeconcept();
- result.replace(c);
+ if (t.hasval() || t.p->links.size() != 0) { throw makeconcept().link(is, "concept-not-empty", concept, t); }
+ result = t;
+ t.replace(s);
});
ahabit(copy-data-to, ((source, s), (target, t)),
{
+ if (t.hasval()) { throw makeconcept().link(is, "concept-has-data", concept, t); }
t.ptr()->data = s.ptr()->data;
});
+ // if last-context is weird give it a default of nothing
ahabit(concept-unmake, ((last-context, c), (concept-name, n)),
{
ref r = c.get(n);
c.unlink(n);
conceptunmake(r);
});
+ // if a concept or link is set crucial deleting it will be denied. no way
+ // to remove crucial mark is provided. nothing is marked crucial yet.
ahabit(concept-crucial, ((concept, c)),
{
result = c.crucial();
@@ -235,7 +273,7 @@ void createhabits()
});
decls(habit, context);
- ahabit(know-is, ((concept, c), (group, g)),
+ ahabit(set-is, ((concept, c), (group, g)),
{
if (c.linked(is, group)) {
throw (make-concept)().link
@@ -252,28 +290,25 @@ void createhabits()
// a way to iterate or inspect the links of a concept
decl(entry);
- ahabit(make-first-link-entry, ((concept, c)),
- {
- // left over from when allocation was handled by separate function, which
- // I'd like to return to
- //if (le.hasval()) { throw makeconcept().link(
- // is, "already-has-value",
- // concept, le,
- // context, ctx); }
- ref le = makeconcept();
+ ahabit(first-link-entry, ((target, le), (concept, c)),
+ {
+ if (le.hasval()) { throw makeconcept().link(
+ is, "already-has-value",
+ concept, le,
+ context, ctx); }
+ //ref le = makeconcept();
le.link(is, link-entry);
le.val<links_it>(c.links().begin());
le.set(source, c);
poplinkentry(le);
result = le;
});
- ahabit(make-last-link-entry, ((concept, c)),
+ ahabit(last-link-entry, ((target, le), (concept, c)),
{
- //if (le.hasval()) { throw makeconcept().link(
- // is, "already-has-value",
- // concept, le,
- // context, ctx); }
- ref le = makeconcept();
+ if (le.hasval()) { throw makeconcept().link(
+ is, "already-has-value",
+ concept, le,
+ context, ctx); }
le.link(is, link-entry);
le.val<links_it>(--c.links().end());
le.set(source, c);
@@ -296,6 +331,12 @@ void createhabits()
{
return lea.val<links_it>() == leb.val<links_it>();
});
+ ahabit(link-entry-insert-before, ((link-entry, le), (target, t)),
+ {
+ // todo: make clean
+ auto & it = le.val<links_it>();
+ le.get(source).ptr()->links.emplace_hint(it.underlying(), le.get(type), t);
+ })
ahabit(link-entry-unlink, ((link-entry, le)),
{
le.get(source).unlink(le.val<links_it>()++);
@@ -477,9 +518,10 @@ void createhabits()
})
*/
decls(needed, made, known, information, translation);
- ahabit(make-translation-map, ((translation-map, m), (known-map, k, nothing)),
+ ahabit(set-translation-map, ((target, c), (translation-map, m), (known-map, k, nothing)),
{
- result = maketranslationmap(m, k);
+ if (c.isa("translation-map") || c.linked("translation") || c.linked("known")) { throw makeconcept().link(is, "already-has-translation-map-data", concept, c, context, ctx); }
+ result = settranslationmap(c, m, k);
});
ahabit(context-map-into, ((source-context, c1), (translation-map, m), (target-context, c2)),
{
@@ -501,11 +543,30 @@ void createhabits()
result = outer;
});
*/
+ /*
+ ahabit(link-next-step, ((step, s), (next-step, ns)),
+ {
+ if (ns != nothing) {
+ if (s.isa("context-step")) {
+ if (s.linked(next-step)) { throw makeconcept().link(is, "previous-step-already-has-next-step", step, s, context, ctx); }
+ } else if (s.isa("condition-step")) {
+ // think about more.
+ // implementing this here immediately means walking through every step of every branch of the condition.
+ // one approach would be to do this elsewhere. to label the steps when the condition is made, add them to a set, and wire them.
+ // let the caller do step wiring.
+ // seems fastest, haven't reviewed relevency fully.
+ } else {
+ throw makeconcept().link(is, "unexpected-previous-step-type", step, s, context, ctx);
+ }
+ }
+ });
+ */
decls(step, previous);
- ahabit(make-context-step, ((previous-step, ps), (known-information, literals), (needed-information-map, in), (made-information-map, out), (action, act)),
+ ahabit(set-context-step, ((target, t), (previous-step, ps, nothing), (known-information, literals), (needed-information-map, in), (made-information-map, out), (action, act)),
{
+ if (t.linked(needed-map) || t.linked(made-map) || t.linked(action)) { throw makeconcept().link(is, "concept-links-collide", concept, t, context, ctx); }
if (ps != nothing && ps.linked(next-step)) { throw makeconcept().link(is, "previous-step-already-has-next-step", previous-step, ps, context, ctx); }
- result = intellect::level1::a("context-step");
+ result = intellect::level1::a("context-step", t);
result.link(
//habit, context-action,
needed-map, maketranslationmap(in, literals),
@@ -515,10 +576,15 @@ void createhabits()
});
decls(order, steps);
- // make steps doesn't allow for name, and isn't used in level2.cpp <====
- ahabit(make-steps, ((existing-concept, nam, nothing), (information-order, io, nothing)),
+ ahabit(set-steps, ((target, t), (information-order, io, nothing)),
{
- result = (nam == nothing) ? makeconcept() : nam;
+ if (t.linked(information-needed) || t.linked(next-step)) {
+ throw makeconcept().link(is, "concept-links-collide",
+ concept, t,
+ context, ctx);
+ }
+ result = t;
+ a(steps, t);
ref infn = intellect::level1::a(habit-information-needed);
result.set(information-needed, infn);
ref posinf = infn;
@@ -547,17 +613,19 @@ void createhabits()
});
decls(condition);
// steps must be actual steps, not a list of steps
- ahabit(make-condition-step, ((previous-step, ps), (condition, cond), (steps, s, nothing)),
+ ahabit(set-condition-step, ((target, t), (previous-step, ps, nothing), (condition, cond), (next-steps, s, nothing)),
{
+ if (t.linked(needed-map) || t.linked(made-map) || t.linked(action)) { throw makeconcept().link(is, "concept-links-collide", concept, t, context, ctx); }
if (ps != nothing && ps.linked(next-step)) { throw makeconcept().link(is, "previous-step-already-has-next-step", previous-step, ps, context, ctx); }
if (s == nothing) { s = makeconcept(); }
- result = intellect::level1::a("condition-step").link(
+ result = t;
+ intellect::level1::a("condition-step", t).link(
needed-map, maketranslationmap(makeconcept().link(condition, cond), makeconcept().link(next-steps, s)),
action, condition
);
if (ps != nothing) { ps.set(next-step, result); }
});
- ahabit(condition-action-add, ((condition-action, ca), (value, v), (step, s)),
+ ahabit(condition-step-add, ((condition-step, ca), (value, v), (step, s)),
{
ca.get(needed-map).get(known).get(next-steps).set(v, s);
});
diff --git a/starts/meaning-vm/level2.cpp b/starts/meaning-vm/level2.cpp
index 990ea45..ac4828e 100644
--- a/starts/meaning-vm/level2.cpp
+++ b/starts/meaning-vm/level2.cpp
@@ -151,6 +151,110 @@ ref makestep(ref last, ref action, std::initializer_list<char const *> resultand
// like closest friend, want to be friends for real, and tell both of our real
// stories.
+
+
+
+
+
+
+
+
+
+
+
+
+using namespace std;
+void parse(string script)
+{
+ stringstream ss(script);
+ ss >> cmd;
+ if (cmd == "when") {
+ ref args = makeconcept();
+ string name;
+ ss >> name;
+ while (true) {
+ string arg;
+ ss >> arg;
+ if (arg == "[") { break; }
+ args.link("information-order", arg);
+ }
+ ref result = (set-steps)(name, args);
+ ref laststep = result;
+ map<string,ref> labels;
+ labels["return"] = nothing;
+ // when dump group [
+ // = is-in-set in-set group
+ // ? is-in-set if true go return.
+ // period-at-end: goto.
+ // comma-or-colon-at-end: label
+ // output-name group
+ // output-name ":" // quotes mean always-global
+ // ]
+ //
+ // proposing expression-based now.
+ // haven't resolved inherited name-contexts with literal strings fully.
+ // working on conditions.
+ // propose if tracks last step
+ // when if ends, adds last step to condition's set of last steps
+ // then next step after condition can wire to all steps in the set.
+ // can use 1-element set for normal steps.
+ // change step-creation to not automatically wire.
+ // and reconsider condition-step to not use its next-step attribute.
+ // instead its conditions decide what the next step is.
+ // looks good for conditions. fix names and update whole thing.
+ while (true) {
+ string label, action, result;
+ ss >> action;
+ if (action == "]") { break; }
+ if (action[action.size()-1] == ':' || action[action.size()-1] == ',') {
+ label = action;
+ label.resize(label.size() - 1);
+ if (label == "return") { throw makeconcept.link(is, "return-label-used"); }
+ ss >> action;
+ }
+ if (action == "=" || action == "set") { ss >> result; ss >> action; }
+ if (action[action.size()-1] == '.') {
+ // is goto
+ action.resize(action.size() - 1);
+ if (!labels.count(action)) {
+ labels.emplace(action, makeconcept());
+ }
+ labels[action].link("label", action);
+ if (laststep.linked("next-step")) { throw makeconcept().link(is, "jump-from-nowhere", "label", action); }
+ laststep.link("next-step", labels[action]);
+ continue;
+ }
+ ref nextstep = label.size() ? labels[label] : makeconcept();
+ if (action == "if") {
+ ref cond;
+ ss >> cond;
+ ss >> action;
+ if (action[action.size()-1] != '-') {
+ throw makeconcept().link(is, "condition-is-not-label", "action", action);
+ }
+ action.resize(action.size()-1);
+ if (!labels.count(action)) {
+ labels.emplace(action, makeconcept());
+ }
+ (condition-step-add)(laststep, cond, labels[action]);
+ }
+ if (action == "?" || action == "pick") {
+ string cond;
+ ss >> cond;
+ laststep = (set-condition-step)(nextstep, laststep, cond, makeconcept().link("anything", "nothing"));
+ // todo: make a noop for 'anything' and use it in following actions
+ // todo: handle if
+ } else {
+ // otherwise, action is an action, and we have to read the right number o args
+ // if last-step is condition, connect to 'anything'
+ // oooogh
+ }
+ }
+ } else {
+ throw ref("parse-error").link("script", script, "unexpected-word", cmd);
+ }
+}
+
int main()
{
createhabits();
@@ -198,8 +302,10 @@ int main()
});
// dump changes to expand from a different node
+ // propose we make script interpreter. much faster in longer term.
+
// I guess I'd better code dump as a behavior.
- begin(dump, concept);
+ begin(dump, set); // change the verbose dump habit to use responsibility-of-interest.
// hey ask the opencoggers if they have a syntax sugar library
// they must if they built a whole robot
// no reply on opencog chat. could check hansen robotics repo or ml.
@@ -247,10 +353,162 @@ int main()
end(dump);
ref memoryfile("memory-000.txt");
- decl(memory-000.txt)
- decls(responsiblefor, responsibility, of, interest);
+ decls(responsiblefor, responsibility, interest);
link(responsibility-of-interest, responsiblefor, dump);
- for (ref a = dump; a.
+ for (ref a = dump; a.linked("next-step"); a = a.get("next-step")) {
+ (responsibility-of-interest).link(responsiblefor, dump);
+ }
+ // structure of steps
+ // [action] [parameter->value ...] repeat
+ // [active memory too small to resolve concern around shape of literals in context]
+ // make value quoted, like it already is.
+ // [parameter->`value]
+ //
+ // steps written can just be
+ // action value value value
+ //
+ // a definition of a list of steps
+ // internal structure (ternary nodes)
+ // (name arg->arg1 arg->arg2 arg->arg3)
+ // ohhhhh hmm
+ // so, if it isn't simplified, there's room for adding more information to stuff. like, arg-must-be-animal
+ // probably wnt arg1 replaceable with [is->arg name->arg1]
+ // can make a norm for general expandable structures
+ // value->
+ // will need strucure definitions to do it really usefully though
+ // is->arg
+ // arg->
+ // we want to tag it with additional stuff, optionally
+ // written structure
+ // steps name arg1 arg2 arg3 arg4
+ // {
+ // label: action arg1 arg2 arg3
+ // action arg1 arg2 arg3
+ // }
+ //
+ // hmm
+ //
+ // let's try to make it c code, how about? until we can summarize better?
+ //
+ // walk-to street
+ //
+ // this is faster to implement. doesn't matter how it looks.
+ //
+ // when walk-to destination [
+ // START: intermediary = get-middle origin destination
+ // // each step could also be a condition that branches to other steps
+ // pick intermediary [
+ // school [ START ]
+ // desk [
+ // stand-up
+ // leave-room
+ // ]
+ // ]
+ // ]
+ // it might make sense to use yaml or something
+ // is easier. rmember to implement comments. maybe #[ name free-text ] , dunno
+ // what we want is links. [ name type target type target ] seems good.
+ // [ ] might open a context with local names, eventually
+ //
+ // when dump concept [
+ // = found-in-set in-set concept
+ // ? found-in-set true return <-- return is label at end
+ // write-name concept
+ // write-name ':'
+ // write-endl
+ // put-in-set concept
+ // link-entry = make-first-link-entry concept
+ // while-1:
+ // has-target = linked link-entry 'target' // propose '' can force something to be global. is also for clarity.
+ // has-target if false break-1
+ // write-name ' '
+ // link-type = get link-entry 'type'
+ // write-name link-type
+ // // we could expand to write-name [ get link-entry 'type' ]
+ // // but just get it working for now
+ // write-name ': '
+ // link-target = get link-entry 'target'
+ // write-name link-target
+ // write-endl
+ // next-link-entry link-entry
+ // while-1
+ // break-1:
+ // concept-unmake context 'link-entry'
+ // link-entry = make-first-link-entry concept
+ // while-2:
+ // has-target = linked link-entry 'target'
+ // has-target if false break-2
+ // link-target = get link-entry 'target'
+ // self link-target
+ // next-link-entry link-entry
+ // while-2
+ // break-2:
+ // concept-unmake context 'link-entry'
+ // ]
+ //
+ // norm: next-step always, unless action is label. then next-step is label.
+ // unresolved concern: want to write habits to do parsing
+ // auxiliary files, can propose to rewrite main file?
+ // good enough for now.
+ // additional unresolved concern: want whole file parseable as a script
+ // okay the outer command is 'when dump concept [ ... ]'
+ // i guess that means we want [] to make a lot of symbols into 1 symbol.
+ // then when is a function that takes 3 symbols
+ // no, when was defined differently.
+ // instead we would do when dump [ concept ] [ ... ]
+ // because could be n args
+ // oh. that looks okay, though.
+ // how about file is made of commands that do parsing.
+ // 'when' then spawns a parser named 'when'. it can process stream however
+ // it desires.
+ // then deserializers, desummarizers need to parse streams
+ // want summarized data without streams, internally?
+ // ummm wouldn't worry about it
+ // propose file is made of lists of symbols, a little
+ // [ when dump concept [ ... ] ] [ etc ]
+ // [when dump concept [...]] [etc]
+ // generalization is valued ...
+ // i like the list approach.
+ // comments can be treated special
+ // nah comments can become [comment free-text]
+ // so we partly propose implementing lisp with brackets
+ // to speed typing , removes shift key
+ // functions get list of symbols passed, and string rep of all for comment preservation
+ //
+ // binary form likely resolves concern.
+ // proposal will be that habit can replace if it will always be able to
+ // reproduce.
+ // ]
+ //
+ // internal structure could be simple too.
+ // hmm want tags. okay, so arguments are objects?
+ // since things are ternary, we could use the link 'type' to store data
+ // oh huh
+ // so, 'first-step' is special, but everything else is an arg.
+ // no, this is what karl's 'is' is for. you make the type store extra data, but if it 'is' an arg,
+ // or 'is' something that is an arg, it counts as an arg.
+ // he wanted to implement a way to lookup types by eveyrthing something is, which is easy to do by
+ // adding an index of categories to level-0.
+ // or the system could do it later.
+ //
+ // so, if oyu want to rewrite steplists, maybe [arg->arg1 arg->arg2 arg->arg3 first->[action->action arg1->source arg2->source arg3->`source]
+ // propose using strings to indicate information, rather than node structure.
+ // this will make a contextual index of word meaning
+ // `source doesn't refer to a unique concept. it means you can only refer to things with names.
+ // everything has a name inside this kind of habit.
+ // i suppose ...
+ //
+ // how scripts look. instead of while/if, are doing 'condition'
+ // influences imply above block is preferred. was leaning towards c++ code as below, takes longer
+ //
+ // ref name(ref arg1, ref arg2, ref arg3)
+ // {
+ // while() {}
+ // if() {}
+ // }
+ //
+ // takes a lot more parsing work, but should be okay
+ //
/*
// for dump, we make a list of contextual actions
ahabit(dump, ((concept, c)),
@@ -277,7 +535,7 @@ int main()
// for some reason it's only running the second loop
// nothing is output on the first
std::cerr << intellect::level1::dump(dump, makeconcept()) << std::endl;
- dump(dump);
+ dump(responsibility-of-interest);
} catch(intellect::level1::ref r) {
std::cerr << intellect::level1::ref(r.ptr()).dump(makeconcept()) << std::endl;
throw;