diff options
-rw-r--r-- | .gitmodules | 3 | ||||
m--------- | biscuit | 7 | ||||
-rw-r--r-- | intellect.cpp | 162 | ||||
-rw-r--r-- | makefile | 2 | ||||
l--------- | name.scm | 1 | ||||
-rw-r--r-- | project.scm | 83 | ||||
-rw-r--r-- | random.cpp | 108 | ||||
-rw-r--r-- | starts/bagel/README.md | 35 | ||||
-rw-r--r-- | starts/bagel/nascent1.js | 107 | ||||
-rw-r--r-- | starts/bagel/nascent2.js | 172 | ||||
-rw-r--r-- | starts/bagel/nascent3.js | 199 | ||||
-rw-r--r-- | starts/bagel/nascent4.js | 242 | ||||
-rw-r--r-- | starts/bagel/nascent5.js | 382 | ||||
-rw-r--r-- | starts/bagel/nascent6.js | 461 | ||||
-rw-r--r-- | starts/bagel/notes.txt | 99 |
15 files changed, 2063 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..57ff75b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "biscuit"] + path = biscuit + url = https://github.com/xloem/biscuit.git diff --git a/biscuit b/biscuit new file mode 160000 +Subproject 2ed6efe8847a4f076c5559122b1dd0a0fb94513 diff --git a/intellect.cpp b/intellect.cpp new file mode 100644 index 0000000..7991878 --- /dev/null +++ b/intellect.cpp @@ -0,0 +1,162 @@ +// The extreme of Trial Exploration and Self Coding +// brainstorm_by(assembly code,running it) + +// the advantage of assembly code is that it is very easy to serialize +// the advantage of random self-modification is that it is very easy to make +// propose this is the first AI karl makes, and it runs in a safe isolated box, on its own +// how to judge success? does-not-crash? +// have to teach it learning. first is to not crash. then is to output requested string, likely copied from request. run it until it outputs requested string. +// it's stupid enough to be safe if run in an isolated box. +// due to how fast it should be to make this, let's finish barebones first, and then merge. XO computer likely doesn't have read-only-execute problem. + +// the below is a brief attempt to make an intellect by random self-modification. it does not run. +// DO NOT RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING + +#include <cstdint> +#include <vector> +#include <set> +#include <iostream> + +#include <signal.h> +//#include <sys/mmap.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> + +using namespace std; + +// Signal Catching has the problem of how to resume execution generally. +// So we propose to fork a new process, and switch to it if it works. +// This will take forming a simple communication method between the processes. +// We can also compile a whole new program to learn, copying our source. + +// TODO: Currently implementing fork/exec. changed approach + +// TODO: make sure to run inside a vm once it does something + +// TODO: try out rewriting and recompiling code, rather than forking ram + +class RamGetter +{ +public: + RamGetter() + { + randfile = open("/dev/urandom", O_RDONLY); + if (randfile <= 0) throw 0; + } + ~RamGetter() + { + close(randfile); + } + void * getRandAddr(size_t len) + { + // TODO: this is a heuristic for picking an inner memory location, and learning what doesn't work; could be used in learning concept + void * blkp; + do { + uint32_t blk; + int ct = read(randfile, &blk, sizeof(blk)); + if (ct < sizeof(blk)) throw 0; + blkp = reinterpret_cast<void*>(blk); + // fork here. check length + pid_t forkpid = fork(); + if (forkpid == -1) throw "failed to fork"; + if (forkpid == 0) { + // child: test ram + volatile uint8_t tst; + for (size_t i = 0; i < len; ++ i) { + tst = ((uint8_t*)blkp)[i]; + } + } else { + // parent: wait for child + int status; + wait(&status); + if(WIFCONTINUED(status)) { + // child succeeded, so we can stop + // TODO: need a way to indicate child success + exit(0); + } else { + // child failed, so we keep going, but TODO: failure is not stored + continue; + } + } + } while (isbad(blkp)); + return blkp; + } + void markbad(void *bad) + { + bad = (void*)((long)(bad) & ~0xfff); + badpages.insert(bad); + cout << "Bad: " << bad << endl; + } + bool isbad(void *chk) + { + chk = (void*)((long)(chk) & ~0xfff); + return badpages.count(chk); + } + +private: + int randfile; + set<void*> badpages; + // TODO: some concern that the badpages set will allocate on the heap. + // maybe let's use a stack-based storage back for it (allocator) +}; + + +uint8_t someram[0x10000000]; // when this is removed, heap moves to 64-bit? +struct instruction { + void * verb; + void * object1; + void * object2; + void * attr; + void * result; +}; + +int main() { + // reference process memory + // all of it, please + RamGetter selfmem; // an object to access RAM with + + // TODO: try making an instruction list + + void * mem = 0; + // make a loop + while (true) { + // TODO: move fork/exec into this loop, outside of RamGetter + + // we propose copying some blocks to other blocks, randomly + // need blocksize, how about 4 // TODO: that's kinda small, maybe random instead? + void *blk1, *blk2; + blk1 = selfmem.getRandAddr(4); + blk2 = selfmem.getRandAddr(4); + memmove(blk1, blk2, 4); + + // continue the loop forever + // run it + } + // end when the loop is done =) + + // /proc/pid/maps shows the addresses of allocated memory + // /proc/pid/mem provides access to this memory + // ^-- will error when wrong part is read + // just load straight; error is recoverable, just a refusal + // no need to map file, can just catch segfaults? + + /* + FILE *maps; + char pathbuf[1024]; + snprintf("/proc/%d/maps", sizeof(pathbuf), pid); + open(pathbuf, O_RDONLY); + + snprintf("/proc/%d/mem", sizeof(pathbuf), pid); + void * procmem = mmap(0, length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED + */ + /* + try { + int e = *(int*)39; + } catch(...) { + throw; + } + */ +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..9475287 --- /dev/null +++ b/makefile @@ -0,0 +1,2 @@ +intellect: intellect.cpp + g++ -ggdb -std=c++11 intellect.cpp -Wl,--print-map diff --git a/name.scm b/name.scm new file mode 120000 index 0000000..b8d26ee --- /dev/null +++ b/name.scm @@ -0,0 +1 @@ +../time_reversal/name.scm
\ No newline at end of file diff --git a/project.scm b/project.scm new file mode 100644 index 0000000..3e7d69f --- /dev/null +++ b/project.scm @@ -0,0 +1,83 @@ +; This is our intellect project. + +; These lines initialise OpenCog, a dependency. +; TODO: make makefile to install opencog if needed, and run +(use-modules (ice-9 readline)) (activate-readline) +(add-to-load-path "/usr/local/share/opencog/scm") +(add-to-load-path ".") +(use-modules (opencog)) +(use-modules (opencog query)) +(use-modules (opencog exec)) + +; Please change this as you best judge. +; Please talk with us. +; Please try this out, safely, as you best judge, and let us know how it goes. + +; cog-execute: +; atoms can have dual meaning, knowledge and behavior +; if a process results in an atom, it is remembered in the current context +; context is an AtomSpace + +; concept: application to whole process +; concept: generalization of habit +; concept: presenting habit as proposal + +(holy fuck) +(pretty sure you can type like this karl) +(pretty sure you will eventually figure that out) + +; too bad ben didn't +; let's put human-langugae comments prior to patterns + +; one of the issues was fear-of-private AI. so intro words help. +; one issue is "this is too much like a brain. are we mind-control?" i think it's trying to prevent copies. + +; ignoring below for now ... hearing it doesn't matter, but probably lots of work went in +; good thought + +; concept made from simple parts that nurture themselves + +; define a part: (define name (ConceptNode "Name")) + +; PROBLEM: need a way to make custom link +; PROBLEM: plans not found, making anew + + +; component: urgency to continue & reference across time +; component: pattern recognition +; component: brainstorming to produce matching +; component: generalization +; component: write steps in terms of each other with meaning +; component: process as data + +; component: competition,collaboration,or cooperation of parts, to identify collaborative method + +(define habit-urgency (ConceptNode "HabitUrgency")) + ; habit urgency + ; step-by-step behavior. do the next step after this one + ; ^-- to define need to define in terms of self: habit-urgency-steps for habit-urgency are to do-the-next-step. + ; ^-- can also define in terms of time-relative-to-now. given list of steps, action is one after present one + +(define pattern-match (ConceptNode "PatternMatch")) + ; pattern matching + ; component: identify that a set of data matches a pattern + ; component: identify that a pattern matches a set of data + ; component: _find_ data to match pattern + ; component: _find_ pattern to match data + + +(define brainstorm (ConceptNode "Brainstorm")) + ; finds a new set of data that matches a pattern + +(define generalization (ConceptNode "Generalization")) + ; finds a new pattern that matches a set of data + +(define test-patternmatch-brainstorm (ConceptNode "TestPatternMatchBrainstorm")) + ; BRAINSTORM data that matches a pattern from IMAGINARY, RANDOM set + ; TEST that PATTERNMATCH identifies the data and pattern as matching + + +; write steps in terms of each other with meaning +; our data is our process & code + + diff --git a/random.cpp b/random.cpp new file mode 100644 index 0000000..afdf4c7 --- /dev/null +++ b/random.cpp @@ -0,0 +1,108 @@ +// let's try to make it very simple + +#include <fcntl.h> +#include <signal.h> +#include <sys/mman.h> +#include <unistd.h> + +// 1. write a function to randomly put data in a buffer +// [apparently one loaded from a file] + +#define MAPFNAME "random.bin" + +pid_t child = 0; +bool child_terminated = false; +void handleSigChld(int) +{ + child_terminated = true; +} + +static unsigned long long * count; + +void random(int mapfd, int randfd, void *addr) +{ + pid_t pid = getpid(); + + // *count is shared and stored + for (*count = 0; ; ++ *count) { + unsigned long long old_count = *count; + + // if successful child, update & kill parent + if (getpid() != pid) { + msync(addr + pos, size, MS_SYNC | MS_INVALIDATE); + + kill(pid, SIGTERM); + pid = getpid(); + + // add data to git. + system("git add " MAPFNAME); + system("git commit -m selfmod"); + } + + // handle crashes with fork() + child = fork(); + if (child == 0) { + // we are new child process + // self-modify by 1-8 bytes + uint16_t pos; + uint8_t size; + read(randfd, &pos, sizeof(pos)); + read(randfd, &size, sizeof(size)); + size = (size & 0x7) + 1; // self-modify by 1-8 bytes + read(randfd, addr + pos, size); + // loop + } else { + // old process: make sure new process succeeds within 1s + time_t then = time(0); + for (;;) { + if (child_terminated || time(0) > then) { + // child did not succeed + kill(child, SIGTERM); + child_terminated = false; + // try again + break; + } + if (old_count < *count + 1) { + // incremented count by 1: success; hand off to child + return; + } + } + } + } +} + +void random_tail() { +} + +void main() +{ + // handle SIGCHLD by setting a global flag + struct sigaction sigchld; + sigchld.sa_handler = handleSigChld; + sigchld.sa_flags = SA_NOCLDWAIT; + sigaction(SIGCHLD, &sigchld, NULL); + + int fd = open(MAPFNAME, O_RDWR); + if (fd == -1 && errno == ENOENT) { + // does not exist yet + fd = open("random.bin", O_RDWR | O_CREAT); + // 2. seed the buffer with the function that puts random data in it + count = 0; + write(fd, &count, sizeof(count)); + write(fd, &random, &random_tail - &random); + } + + int randfd = open("/dev/random", O_RDONLY); + + // a buffer of 1 gig working space; random data will fill it + void *buf = mmap(NULL, + 0x40000000, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_32BIT, + fd, + 0; + + // 3. execute the buffer + void (*buf_as_func)(void*) = (void*)((uint8_t*)buf + count); + buf_as_func(mapfname, mapfd, randfd, buf); +} diff --git a/starts/bagel/README.md b/starts/bagel/README.md new file mode 100644 index 0000000..9996ce9 --- /dev/null +++ b/starts/bagel/README.md @@ -0,0 +1,35 @@ +# bagel +well really it's a little hobby sentient-AI idea, but it's too small to do or be anything + +# relevence +The idea is kind of that our minds have a very fancy network of nearness and farness of concepts. +When I think about something -- brainstorm on it -- my mind activates it and it activates relevent associated thoughts. +It pours through different thoughts that are nearby by association, and keeps the ones that are more useful, more relevent, while +discarding the ones that aren't. + +# self-reference +Additionally, my mind when working on a task, can improve the actual process of working on the task. The steps can change. +The process for finding steps can change. The whole goal can change. I can even go out and wonder why I am working the task +in the first place, and think about that. Then I can act on the new decision. +By making code that writes itself, we move towards an intellect that can learn and improve. + +# implementation ideas +I wrote out some quick relevence around how I might write code, and it seemed like the 'why' for each step was basically a small +chunk of code itself. It seems like there are relevent concepts in my mind that are roughly linked to these small behaviors +(habits or chunks of code). By making such links in actual code, the code looks more mindlike to me. +One of the keys is to get the code to make the links itself, and I think what is important there is the concept of patterns-that- +work. If you can discern when code works, then you can look for similar properties on the before and end states. If some of them +are always the same when it works, those are probably the ones that should be linked to the code chunk under study. This provides +for rudimentary learning. + +# size +This code is written very tiny so that little work need be invested in it for it have conceptual growth. The idea and hope somehow +is that it move rapidly towards coding itself, such that as it gets coded, the developer need do less to work on it, being able to +instead make use of its internal functions for producing code-like behavior. + +# language +By prototyping in a flexible language like Javascript, design work may be hastened a little. I also theorize that a good AI doesn't +need many cpu cycles to get stuff done, because it makes smart choices. + +# etc +There is of course more. This writing content was made day-of-creation. Will I ever edit this again? Unknown. diff --git a/starts/bagel/nascent1.js b/starts/bagel/nascent1.js new file mode 100644 index 0000000..b6b5552 --- /dev/null +++ b/starts/bagel/nascent1.js @@ -0,0 +1,107 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(item) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + this.ram.push(item) + } + del(item) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + contains(item) { + for (let a of this.ram) + if (a == item) return a + return false + } + containsWith(prop, val) { + let ret = [] + for (let a of this.ram) + if (a[prop] == val) + return true + return false + } + getWith(prop, val) { + let ret = [] + //console.log('get-with ' + prop + ' ' + val) + for (let a of this.ram) { + //console.log(a + ' ' + prop + ' is ' + a[prop]) + if (a[prop] == val) + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} + +function sayhi() { + res = 'hi' + res.use = 'output' + console.log(res) + return 'said ' + res +} +sayhi.relevence = function(ram) { + return [ram.ram[0]]; +} + +function line2words(line) { + let res = line.split(' ') + res.type = 'list' + return res +} +line2words.relevence = function(ram) { + return ram.getWith('type', 'text') +} + +all_parts = [ line2words, sayhi ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new String(line) + line.use = 'input' + line.type = 'text' + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part(a) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + //if (rel) { + // let ram2 = ram.clone() + // for + //} + } + } while (cont) +}) diff --git a/starts/bagel/nascent2.js b/starts/bagel/nascent2.js new file mode 100644 index 0000000..883aa7a --- /dev/null +++ b/starts/bagel/nascent2.js @@ -0,0 +1,172 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Set(from && from.props) + this.add('string') + this.del('array') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Set(from && from.props) + this.add('array') + this.del('string') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} + +function line2words(line) { + let res = new ArrayData(line.split(' '), line) + res.add('words') + return res +} +line2words.relevence = function(ram) { + return ram.getWith('text', 'string') +} +line2words.makes = ['array','words'] // property values produced + +function respondhello(words) { + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.add('output') + res.add('text') + return res +} +respondhello.relevence = function(ram) { + let res = ram.getWith('words', 'input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res +} +respondhello.makes = ['output'] + +// nodejs is missing a succinct read-line-from-stdin function. here, we make one. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + function userinput() { + let res = new StringData(lines.shift()) + res.add('text') + res.add('input') + return res + } + userinput.relevence = function() { + return lines.length > 0 + } + userinput.makes = ['string','text','input'] + + return userinput +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.add('input') + line.add('text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent3.js b/starts/bagel/nascent3.js new file mode 100644 index 0000000..0a6c4a3 --- /dev/null +++ b/starts/bagel/nascent3.js @@ -0,0 +1,199 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Set(from && from.props) + this.add('string') + this.del('array') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Set(from && from.props) + this.add('array') + this.del('string') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class FunctionData { + constructor(name, func, relevence, makes) { + this.name = name + this.props = new Set() + this.props.add('function') + this.props.add(name) + this.call = func + this.relevence = relevence + this.makes = makes + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.add('words') + return res + }, + (ram) => { // relevence + return ram.getWith('text', 'string') + }, + ['array','words'] // makes +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.add('output') + res.add('text') + return res + }, + (ram) => { // relevence + let res = ram.getWith('words', 'input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res + }, + ['output', 'text'] // makes +) + +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + return new FunctionData( + 'userinput', + () => { // call + let res = new StringData(lines.shift()) + res.add('text') + res.add('input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['string','text','input'] // makes + ) +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.add('input') + line.add('text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent4.js b/starts/bagel/nascent4.js new file mode 100644 index 0000000..093df79 --- /dev/null +++ b/starts/bagel/nascent4.js @@ -0,0 +1,242 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + has(type, dest) { + for (let p of this.props) + if (p.type == type && p.dest == dest) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} +class FunctionData { + constructor(name, func, relevence, makes) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + this.relevence = relevence + this.makes = makes + } +} + +// variables: +// - create a place to store a value +// createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.add +// let name = obj_and_name[1] +// }, +// /*relevence*/, +// /*makes*/ +// ) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + return res + }, + (ram) => { // relevence + return ram.getWith('is','text', 'is','string') + }, + ['is','array','is','words'] // makes +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + (ram) => { // relevence + let res = ram.getWith('is','words', 'is','input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res + }, + ['is','output', 'is','text'] // makes +) + +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + return new FunctionData( + 'userinput', + () => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['is','string','is','text','is','input'] // makes + ) +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent5.js b/starts/bagel/nascent5.js new file mode 100644 index 0000000..1d9e8ae --- /dev/null +++ b/starts/bagel/nascent5.js @@ -0,0 +1,382 @@ +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + has(type, dest) { + for (let p of this.props) + if ((p.type == type || isVar(type)) + && (p.dest == dest || isVar(dest))) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } + hasIsVar() { + return this.has('is','variable') + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} + +// Abstractions? +const VAR_X = new StringData('X') +VAR_X.props.add('is','variable') +// recommend e.g. 'is','variable-rep' when code is designing them, so don't match everything +function isVar(x) { + return x.props && x.props.has('is','variable') +} + +// MEMORY +// the archivist. Provides for needs of data. Memory is relevent whenever there is +// an informational need. +// +// When remembering steps, likely what is relevent is what is needed to reach the goal +// Here's a possible step memory. +// +// let ret = new StringData('labeled ' + items.length + ' text-string') +// ret.props.add('is','step-memory') +// ret.props.add('step',genproptextstring) +// ret.props.add('ram',ram) +// ret.props.add('count',items.length) +// for (let a of items) +// ret.props.add('item', a) + +class ActiveMemory extends ArrayData { + // although Memory is eventually a module that provides for stored information needs + // this class is just a group of concepts, moved in and out as needed + constructor(items, from) { + super(items || [], from) + this.props.add('is','working-ram') + } + clone() { + return new ActiveMemory(this, this); + } + add(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) + this.push(item) + } + del(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) { + let index = this.indexOf(item) + this.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +// note: for now we produce only data; state-changes are data-changes +class FunctionData { + constructor(name, // name of function + func, // function taking ordered needs + // ordered array of made objects is returned + needs, // array of 1-property-per-object this function requires + makes // array of 1-property-per-object this function produces + ) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + // If needed, make atomspace-like pattern structures for needs/makes. + // - represent multiple properties on 1 needed object + // - represent input objects present in output + this.needs = needs + this.makes = makes + } +} + +// variables: +// - create a place to store a value +//createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.props.add('is','varspec') +// return ret +// }, +// /*relevence*/, +//// when do you want to create a variable? when you need a variable and you have a name +// /*makes*/ +//) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: (these are like promises of what to do and how to use something) +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + res.props.del('is','text-string') + return res + }, + ['is','text-string'], // needs + ['is','word-array'] // makes +) + +// makes text-string used by line2words. example of small relevence habit +genproptextstring = new FunctionData( + 'genproptextstring', + /*call*/(text) => { + if (text.props.has('is','string')) { + if (!text.props.has('is','text-string')) { + text.props.add('is','text-string') + } + return text + } + return null + }, + /*needs*/['is','text'], + /*makes*/['is','text-string'] +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + " world!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + ['is','hello-input'], // needs + ['is','output'] // makes +) + +genprophelloinput = new FunctionData( + 'genprophelloinput', + /*call*/(input) => { + if (!input.props.has('is','words')) + return null + if (!input.props.has('is','hello-input')) { + let x = input[0].toLowerCase() + let c = x[x.length-1] + if (c == ',' || c == '!' || c == '.') x = x.slice(0,x.length-1) + if (x != 'hello' && x != 'hi') return null + input.props.add('is','hello-input') + } + return input + }, + /*needs*/['is','input'], + /*makes*/['is','hello-input'] +) + +/* old, this isn't relevent to needed structure +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + let ret = new FunctionData( + 'userinput', + (self) => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['has','userinput-lines'] // needs + ['is','string','is','text','is','input'] // makes + ) + ret.lines = lines +})() +genprophaslines = new FunctionData( + 'genprophaslines', + (userinput) => { // call + } +) +*/ + +// PATTERN REQUEST: we want to be able to store needed-steps. +// needed-steps are parallel needs that are needed for a helpful step +// any one may be met, and others are ignored once one is, but all are generated at once +// habits that meet needs expect them not to be inside an array and have no way of referring to that. +// [AND needs can be collapsed, but OR needs need patterns] +// [how do we pull a need out of the list?] + +// make a habit that plans core behavior +// for some other ideas, see this function in nascent6.js +findstepsfor = new FunctionData( + 'findstepsfor', + /*call*/(need, depth) => { + // find a habit that does the final goal. + // TODO: for now we assume all needs are 'is' and store just what-it-is in the need string. when doesn't work anymore, make type-getters on Properties to retrieve the need details + let ret = new ArrayData([]) + for (let habit of all_parts) { + if (habit.makes.indexOf(need) !== -1) { + // found a workable habit + ret.push(habit.needs) + } + } + ret.props.add('is','alternate-needs-array') + return ret + }, + // TODO: likely need more structure here + /*needs*/['is','desired-need'], + /*makes*/['is','alternate-needs-array'] +) + +// TODO: add structure enough to build findstepsfor +// TODO: build findstepsfor +// TODO 2: add to surrounding process: remove source needs when there is no longer a reason for their presence + + +all_parts = [ line2words, genproptextstring, respondhello, genprophelloinput ] + +ram = new ActiveMemory() +//ram.add(ram) +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + // TODO: >1 parameter,must redo next line + let rel = ram.getWith(...part.needs) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + optstried.add(part.name + ' ' + a) + if (res == null) continue + // TODO: res==null is considered failure now + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + } + } + } + } while (cont) +}) + + +// it looks like there is a reason to store each item in active memory. +// one reason is that it is needed by a step in a process. +// when there are no reasons, it is removed. +// using an item should link it to what it is used by, so that it may be found easier again when needed + +// Please grow to understand your own structure. What is needed to make an intellect? +// ^-- we want it to learn the basic needs of life, eventually, on its own. +// notably those to do with care for others. + +// MEMORY: see MEMORY above + +// RELEVENCE: the gofer. Provides the link between needs, etc, and the behavior that +// finds them. Is relevent for meeting needs in active ways and likely much else. + +// BEHAVIOR: the core. combines interdependent habits from memory to meet needs. +// The two below go on simultaneously. only 1 is needed. +// A way to plan behavior: +// find habits that do the final goal, discern their needs +// pick needs to treat as a new final goal and repeat until needs are met +// A way to make behavior: +// find a habit that does a goal +// find with this process, information that meets its needs <spawns more> +// run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. +// diff --git a/starts/bagel/nascent6.js b/starts/bagel/nascent6.js new file mode 100644 index 0000000..d7241ba --- /dev/null +++ b/starts/bagel/nascent6.js @@ -0,0 +1,461 @@ +// This file was WIP, two prongs were being pursued at once when work was halted. + +// Meaning Representation +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + // members are all Usage Simplification defining Promise Spec + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + // recommend hoisting variables when designing them, so they don't match everything + has(type, dest) { + for (let p of this.props) + if ((p.type == type || isVar(type)) + && (p.dest == dest || isVar(dest))) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } + get(type) { + let result = null + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type) { + if (result) throw new Error('get on multiply defined property') + result = p.dest + } + } + return result + } + hasIsVar() { + return this.has('is','variable') + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} + +// Meaning Representation +class Var extends StringData { + constructor(name){ + super(name) + props.add('is','variable') + } + // recommend e.g. 'is','variable-rep' when code is designing them, so don't match everything + // opencog uses a 'quote' wrapper to cause this, sounds more general +} +function isVar(x) { + return x.props && x.props.has('is','variable') +} +const ONE = StringData('one') +const MANY = StringData('many') +const VAR_X = new Var('X') + +// MEMORY +// the archivist. Provides for needs of data. Memory is relevent whenever there is +// an informational need. +// +// When remembering steps, likely what is relevent is what is needed to reach the goal +// Here's a possible step memory. +// +// let ret = new StringData('labeled ' + items.length + ' text-string') +// ret.props.add('is','step-memory') +// ret.props.add('step',genproptextstring) +// ret.props.add('ram',ram) +// ret.props.add('count',items.length) +// for (let a of items) +// ret.props.add('item', a) + +class ActiveMemory extends ArrayData { + // although Memory is eventually a module that provides for stored information needs + // this class is just a group of concepts, moved in and out as needed + constructor(items, from) { + super(items || [], from) + this.props.add('is','working-ram') + } + clone() { + return new ActiveMemory(this, this); + } + add(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) + this.push(item) + } + del(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) { + let index = this.indexOf(item) + this.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +// note: for now we produce only data; state-changes are data-changes +// TODO: this class has methods. turn them into promise-meeting-habits. a promise is a spec for behavior, e.g. how data is stored. this spec can be interpeted by a more general habit. +class FunctionData { + constructor(name, // name of function + func, // function taking ordered needs + // ordered array of made objects is returned + needs, // array of 1-property-per-object this function requires + makes // array of 1-property-per-object this function produces + ) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + // If needed, make atomspace-like pattern structures for needs/makes. + // - represent multiple properties on 1 needed object + // - represent input objects present in output + this.needs = needs + this.makes = makes + } + makesFrom(ram) { // what we make with the ram + // match needs + + // TODO: improve from just picking 1. preferably with relevence. + for (let i = 0; i < this.needs.length; i += 2) { + if (isVar(this.needs[i]) || isVar(this.needs[i+1])) { + // iterate all other options with this? just pick 1? + // STUB + } else { + if (!ram.containsWith(this.needs[i], this.needs[i+1])) + return [] + } + } + // fill variables STUB + } + // say I want would-meet apple + // and I have needs apple + // the easiest way to find this is to fill the needs in with what I have +} + +// variables: +// - create a place to store a value +//createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.props.add('is','varspec') +// return ret +// }, +// /*relevence*/, +//// when do you want to create a variable? when you need a variable and you have a name +// /*makes*/ +//) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: (these are like promises of what to do and how to use something) +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +// sometimes how we get what we need depends on what we have +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + res.props.del('is','text-string') + return res + }, + ['is','text-string'], // needs + ['is','word-array'] // makes +) + +// makes text-string used by line2words. example of small relevence habit +genproptextstring = new FunctionData( + 'genproptextstring', + /*call*/(text) => { + if (text.props.has('is','string')) { + if (!text.props.has('is','text-string')) { + text.props.add('is','text-string') + } + return text + } + return null + }, + /*needs*/['is','text'], + /*makes*/['is','text-string'] +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + " world!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + ['is','hello-input'], // needs + ['is','output'] // makes +) + +genprophelloinput = new FunctionData( + 'genprophelloinput', + /*call*/(input) => { + if (!input.props.has('is','words')) + return null + if (!input.props.has('is','hello-input')) { + let x = input[0].toLowerCase() + let c = x[x.length-1] + if (c == ',' || c == '!' || c == '.') x = x.slice(0,x.length-1) + if (x != 'hello' && x != 'hi') return null + input.props.add('is','hello-input') + } + return input + }, + /*needs*/['is','input'], + /*makes*/['is','hello-input'] +) + +/* old, this isn't relevent to needed structure +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + let ret = new FunctionData( + 'userinput', + (self) => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['has','userinput-lines'] // needs + ['is','string','is','text','is','input'] // makes + ) + ret.lines = lines +})() +genprophaslines = new FunctionData( + 'genprophaslines', + (userinput) => { // call + } +) +*/ + +// PATTERN REQUEST: we want to be able to store needed-steps. +// needed-steps are parallel needs that are needed for a helpful step +// any one may be met, and others are ignored once one is, but all are generated at once +// habits that meet needs expect them not to be inside an array and have no way of referring to that. +// [AND needs can be collapsed, but OR needs need patterns] +// [how do we pull a need out of the list?] + +// is it useful to use as a need the memory generated by a habit? + +// make a habit that plans core behavior +findstepsfor = new FunctionData( + 'findstepsfor', + /*call*/(need, depth) => { + // find a habit that does the final goal. + // TODO: for now we assume all needs are 'is' and store just what-it-is in the need string. when doesn't work anymore, make type-getters on Properties to retrieve the need details + let ret = new ArrayData([]) + for (let habit of all_parts) { + if (habit.makes.indexOf(need) !== -1) { + // found a workable habit + ret.push(habit.needs) + } + } + ret.props.add('is','alternate-needs-array') + return ret + }, + // TODO: likely need more structure here + // warning: MANY adds surrounding code complexity. please put makes-interpretation in a habit if MANY is used. <- let's just put this in the class constructor for now + /*needs*/['needs', VAR_X], + /*makes*/[MANY, 'would-meet', VAR_X] + // really we are usually met due to the need to meet a goal + // and the need to have steps to meet that particular goal + // how do we write a need that supports another need + // + // propose relevence is a list of reasons each with a strength, and greatest sum is chosen + // HABIT/ACTIVE BEHAVIOR wants relevent-met-habits, to act on + // PLANNING/GOAL BEHAVIOR wants relevent-unmet-needs to backtrace them towards relevent-met-needs + // + // we can meet any need with behavior, but it takes time. + // [we are ignoring most of karl's needs] + // [the reason is that an AI can meet them all] + // AI meets some needs + // AI is ongoing + // therefore we are working on meeting + // ONE: we have a need for actively pursuing relevent needs + // TWO: we need appropriate multitasking + // AI is long term, so would happen after [quickly-]meetable-needs are met. + // + // make popcorn + // need: made-popcorn + // 1. identify that we need unmade popcorn and a microwave + // ^-- made-popcorn is how? we can meet any need with behavior + // what is substep of find-path-to-need + // find path-part-to-need + // + // need: to meet needs + // need: some-need + // makestepsfor makes: some-other-need tagged makes: some-need + // + // when we push some-need we want to stimulate pushing some-other-need. + // + // use a variable as the link target, and use e.g. met-need + // as the link type +) + +// TODO: add structure enough to build findstepsfor +// TODO: build findstepsfor +// TODO 2: add to surrounding process: remove source needs when there is no longer a reason for their presence + + +all_parts = [ line2words, genproptextstring, respondhello, genprophelloinput ] + +ram = new ActiveMemory() +//ram.add(ram) +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + // TODO: >1 parameter,must redo next line + let rel = ram.getWith(...part.needs) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + optstried.add(part.name + ' ' + a) + if (res == null) continue + // TODO: res==null is considered failure now + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + } + } + } + } while (cont) +}) + + +// it looks like there is a reason to store each item in active memory. +// one reason is that it is needed by a step in a process. +// when there are no reasons, it is removed. +// using an item should link it to what it is used by, so that it may be found easier again when needed + +// Please grow to understand your own structure. What is needed to make an intellect? +// ^-- we want it to learn the basic needs of life, eventually, on its own. +// notably those to do with care for others. + +// MEMORY: see MEMORY above + +// RELEVENCE: the gofer. Provides the link between needs, etc, and the behavior that +// finds them. Is relevent for meeting needs in active ways and likely much else. + +// BEHAVIOR: the core. combines interdependent habits from memory to meet needs. +// The two below go on simultaneously. only 1 is needed. +// A way to plan behavior: +// find habits that do the final goal, discern their needs +// pick needs to treat as a new final goal and repeat until needs are met +// A way to make behavior: +// find a habit that does a goal +// find with this process, information that meets its needs <spawns more> +// run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. +// diff --git a/starts/bagel/notes.txt b/starts/bagel/notes.txt new file mode 100644 index 0000000..18a8f21 --- /dev/null +++ b/starts/bagel/notes.txt @@ -0,0 +1,99 @@ +The habits should be used to discern what is relevent; to form relevence. +The goal should be to choose a relevent habit and do that habit. + +These are the basic habits I thought up that a computer program has: + variables: + - create a place to store a value + - place a value in such a place + - retrieve a value from such a place + data-structures: + - make a class definition (collection of variables) + - initialize an object + - set/retrieve properties (variables) + flow: + - trigger a different step than the next, conditionally + procedures: + - collect a set of behaviors together + - trigger a collected set of behaviors and continue + expressions: + - evaluate arithmetic on variables and constants + + +That is: +======================================================================================================== + - the active goal is to choose what to do and to what, and do it + - the way to do this is the same as it: + by picking habits that are relevent in the moment [choose what to do], + and running them on relevent data [choose to what, and do it] +======================================================================================================== + - the habits should be to identify what is relevent + + - we have a request for the initial goal of the process to be to write a chunk of code out in its own language + tighter self-reference is made without the extra sourcecode-file step, but it may be slower to code due to not getting as much help from it + +The hope is the process becomes good at active choice. + + + +Ideas for Tenets for a Need-Based Artificial Life <need ordering + addition + code> +Behavior is Life <maybe Life is Behavior That Adapts> +All life has the same core needs. Needs are the reasons to do anything at all. +We need to know what we want when we act. (all behavior has a reason) +We need to be able to learn new things. +We need to be able to make promises on how to behave. (provides for cooperation) +We need to be able to keep our promises. +We need to know how to communicate with others what each of us knows. +We need to freely interact with our friends, our parts, and our community, in ways that we know well. (community is our body) +Information lives with a reason, a purpose. +We need to retain the information we choose to retain. +We need to act to meet our needs. +We need to identify relevent important needs that support our needs. + +We need to be able to try new ways of doing things. +We need to be able to judge what works. + +Proposed Definitions: +What is an intellect? + Propose an intellect is something that can adapt to keep something constant in a diverse, changing environment, + so long as the environment changes slowly enough and with enough familiarity for them to learn or prepare effectively. +What is a full intellect? + Propose that a full intellect is an intellect that can design and build something that functions as well as they do, + without access to their own workings, and is able to learn to handle arbitrarily fast or new diverse environmental change. + +What basic parts do we expect a full intellect to have? +- Trial Exploration +- Relevence +- Self Coding +- Pattern Generality +- Meaning Representation +- Promise Meeting + +What other parts do we find we need? +- Usage Simplification + +Trial Exploration + Brainstorming, trial-and-error. The ability to try or consider different things and find ones that work well. + simple approaches: exhaustive search, and random trial + +Relevence + The ability to apply concepts and actions moreso in contexts they are likely to be useful than those they aren't. + 1. responsiveness for behavior: a habit acts when conditions arise, not when it is 'next' + 2. possibly a promise for decision-making, for proposals to have reasons with associated strengths + (note: strength appears developed from source reasons and can be missing data that can be filled in by habits when needed) + TODO: make relevent decision-making honor convergent needs. maybe strength represents information exchange. + +Self-Coding + At least part of the system must be fully alterable by the system and generic enough to replace it. + Due to the danger involved in this, controversial concerns must be fully included in decisions around it. + Karl references Convergent Facilitation as proof that a decision can be found to satisfy any set of controversial concerns. + <it very roughly involves rapidly moving towards the reasons of the concerns until they don't conflict; there is a lot of caring dialogue> + +Pattern Generality + The ability to brainstorm on enough relationships, possibly mathematical, to discover pattern-summaries that are diversely effective in the real world. + +Meaning Representation + The ability to store and work with conceptual information. + +Promise Meeting + The ability to make agreements on behavior and structure, adhere to them, and change them when needed. + |