From 7da8cc5684cd56616a7578756d40523973a608c9 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Wed, 16 Oct 2019 16:45:39 -0400 Subject: simple code for functions that act on relevent data. if one codes it to run itself using relevence, it should grow if the relevence is fancy enough. --- nascent.js | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 nascent.js diff --git a/nascent.js b/nascent.js new file mode 100644 index 0000000..b6b5552 --- /dev/null +++ b/nascent.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) +}) -- cgit v1.2.3 From 9b0b40bfd12a7a5a941dc64e6f04af0237a550f3 Mon Sep 17 00:00:00 2001 From: fuzzyTew Date: Wed, 16 Oct 2019 16:56:01 -0400 Subject: Create README.md --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1a72de1 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# 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. + +# etc +There is of course more. This writing content was made day-of-creation. Will I ever edit this again? Unknown. -- cgit v1.2.3 From a9d513755b11fb6463c0412754a2a5705bca6c7d Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Thu, 17 Oct 2019 07:45:33 -0400 Subject: add notes re basic core meaning --- notes.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 notes.txt diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..2f37620 --- /dev/null +++ b/notes.txt @@ -0,0 +1,12 @@ +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. + +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 hope is the process becomes good at active choice. + -- cgit v1.2.3 From 6a300e3f9e62333d451ecab4772bb78f3a021db3 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Thu, 17 Oct 2019 08:35:06 -0400 Subject: added two-step behavior, removed property types --- nascent2.js | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 nascent2.js diff --git a/nascent2.js b/nascent2.js new file mode 100644 index 0000000..883aa7a --- /dev/null +++ b/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) +}) -- cgit v1.2.3 From 91690224a115714b2e37460057e3fd5c4879885d Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Thu, 17 Oct 2019 09:02:54 -0400 Subject: made habits into objects --- nascent3.js | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ notes.txt | 5 ++ 2 files changed, 204 insertions(+) create mode 100644 nascent3.js diff --git a/nascent3.js b/nascent3.js new file mode 100644 index 0000000..0a6c4a3 --- /dev/null +++ b/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/notes.txt b/notes.txt index 2f37620..e94986e 100644 --- a/notes.txt +++ b/notes.txt @@ -8,5 +8,10 @@ That is: 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. -- cgit v1.2.3 From 4df65b81480b3b2d36bdb0da41b79a05bf19911b Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Sat, 19 Oct 2019 12:34:12 -0400 Subject: added language components to notes --- README.md | 4 ++++ notes.txt | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/README.md b/README.md index 1a72de1..9996ce9 100644 --- a/README.md +++ b/README.md @@ -27,5 +27,9 @@ This code is written very tiny so that little work need be invested in it for it 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/notes.txt b/notes.txt index e94986e..a20cb8f 100644 --- a/notes.txt +++ b/notes.txt @@ -1,6 +1,24 @@ 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 -- cgit v1.2.3 From 09d78c138d5de72f5ea8f4a121f54a0ba9839840 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Sat, 19 Oct 2019 14:09:56 -0400 Subject: added back typed properties, a different way --- nascent.js | 107 --------------------------- nascent1.js | 107 +++++++++++++++++++++++++++ nascent4.js | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 349 insertions(+), 107 deletions(-) delete mode 100644 nascent.js create mode 100644 nascent1.js create mode 100644 nascent4.js diff --git a/nascent.js b/nascent.js deleted file mode 100644 index b6b5552..0000000 --- a/nascent.js +++ /dev/null @@ -1,107 +0,0 @@ -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/nascent1.js b/nascent1.js new file mode 100644 index 0000000..b6b5552 --- /dev/null +++ b/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/nascent4.js b/nascent4.js new file mode 100644 index 0000000..093df79 --- /dev/null +++ b/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) +}) -- cgit v1.2.3 From 721bf5940cd607198e4d11ed540dabd0a9aa429b Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Sat, 19 Oct 2019 16:19:51 -0400 Subject: found i need to load ram to make relevence be separate habits --- nascent5.js | 288 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 nascent5.js diff --git a/nascent5.js b/nascent5.js new file mode 100644 index 0000000..55fb7c6 --- /dev/null +++ b/nascent5.js @@ -0,0 +1,288 @@ +class ActiveMemory { + // provides for needs of data + 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') + } +} +// inhibition: wants lines to line up in top window +class FunctionData { + constructor(name, // name of function + func, // function taking ordered needs + // ordered array of made objects is returned + relevence, // TEMPORARY; MOVE TO HABIT. function that generates the needs, takes ram + 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 + this.relevence = relevence + 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: +// - 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','text-string'], // needs + ['is','word-array'] // 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','input-words'], // needs + ['is','output'] // 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 + }, + ['userinput-has','lines'] // needs + ['is','string','is','text','is','input'] // makes + ) +})() +// => switching from 'relevence' to 'needs'. <= relevence is the module that processes needs +// TODO: we need to make active memory a Data so that we can pass sets of data to relevence +// TODO: want to move the relevence funcs out of the func defs that use them +// TODO: we have 'is input-words'; can make as makeinputwords from respondhello.relevence +// TODO: we have 'is word-array' instead of 'is words' and 'is array' +// TODO 2: add to surrounding process: remove source needs when there is no longer a reason for their presence + + +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) +}) + + +// 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? + +// MEMORY: the archivist. Provides for needs of data. Memory is relevent whenever there is +// an informational need. + +// 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. +// +// 1 way to make behavior: +// find a habit that does the final goal +// find with this process, information that meets its needs +// run it +// +// specifying the needs is an interesting problem +// but i think our norm is just property specs +// other habits can generate the property specs -- cgit v1.2.3 From 5a548e692abcf226d1a21b5b186ede67dca8b0ff Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Sat, 19 Oct 2019 19:54:15 -0400 Subject: tried making very basic relevence-generators --- nascent5.js | 259 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 170 insertions(+), 89 deletions(-) diff --git a/nascent5.js b/nascent5.js index 55fb7c6..b07afec 100644 --- a/nascent5.js +++ b/nascent5.js @@ -1,57 +1,3 @@ -class ActiveMemory { - // provides for needs of data - 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 @@ -110,12 +56,79 @@ class ArrayData extends Array { this.props.del('is', 'string') } } -// inhibition: wants lines to line up in top window + +// 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 - relevence, // TEMPORARY; MOVE TO HABIT. function that generates the needs, takes ram needs, // array of 1-property-per-object this function requires makes // array of 1-property-per-object this function produces ) { @@ -123,7 +136,9 @@ class FunctionData { this.props = new Properties('function') this.props.add('name', name) this.call = func - this.relevence = relevence + // 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 } @@ -161,35 +176,61 @@ line2words = new FunctionData( (line) => { // call let res = new ArrayData(line.split(' '), line) res.props.add('is','words') + res.props.del('is','text-string') return res }, - (ram) => { // relevence - return ram.getWith('is','text', 'is','string') - }, ['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] + ", user!") + console.log(words[0] + " world!") 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'}) + ['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 res + return input }, - ['is','input-words'], // needs - ['is','output'] // makes + /*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') @@ -198,9 +239,9 @@ userinput = (() => { lines.push(line) }) - return new FunctionData( + let ret = new FunctionData( 'userinput', - () => { // call + (self) => { // call let res = new StringData(lines.shift()) res.props.add('is','text') res.props.add('is','input') @@ -209,21 +250,55 @@ userinput = (() => { () => { // relevence return lines.length > 0 }, - ['userinput-has','lines'] // needs + ['has','userinput-lines'] // needs ['is','string','is','text','is','input'] // makes ) + ret.lines = lines })() -// => switching from 'relevence' to 'needs'. <= relevence is the module that processes needs -// TODO: we need to make active memory a Data so that we can pass sets of data to relevence -// TODO: want to move the relevence funcs out of the func defs that use them -// TODO: we have 'is input-words'; can make as makeinputwords from respondhello.relevence -// TODO: we have 'is word-array' instead of 'is words' and 'is array' +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 +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, respondhello ] +all_parts = [ line2words, genproptextstring, respondhello, genprophelloinput ] ram = new ActiveMemory() +//ram.add(ram) optstried = new Set() steps = [] @@ -241,21 +316,23 @@ readline.createInterface({ cont = false for (let part of all_parts) { //console.log('for-loop-of-parts ' + part.name) - let rel = part.relevence(ram) + // 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 - optstried.add(part.name + ' ' + a) - } } } @@ -269,20 +346,24 @@ readline.createInterface({ // 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: the archivist. Provides for needs of data. Memory is relevent whenever there is -// an informational need. +// 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. -// -// 1 way to make behavior: -// find a habit that does the final goal -// find with this process, information that meets its 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 // run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. // -// specifying the needs is an interesting problem -// but i think our norm is just property specs -// other habits can generate the property specs -- cgit v1.2.3 From 9f3db5ed4e0bf342a159e1d45105bfcaf7b8a7bd Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Tue, 22 Oct 2019 06:56:50 -0400 Subject: developing my plans --- nascent5.js | 17 +++++++++++++++-- notes.txt | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/nascent5.js b/nascent5.js index b07afec..1d9e8ae 100644 --- a/nascent5.js +++ b/nascent5.js @@ -22,7 +22,8 @@ class Properties { } has(type, dest) { for (let p of this.props) - if (p.type == type && p.dest == dest) + if ((p.type == type || isVar(type)) + && (p.dest == dest || isVar(dest))) return true return false } @@ -36,6 +37,9 @@ class Properties { } return false } + hasIsVar() { + return this.has('is','variable') + } } class AbstractData { constructor(from) { @@ -57,6 +61,14 @@ class ArrayData extends Array { } } +// 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. @@ -159,7 +171,7 @@ class FunctionData { //) // - place a value in such a place // - retrieve a value from such a place -// data-structures: +// 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) @@ -270,6 +282,7 @@ genprophaslines = new FunctionData( // [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) => { diff --git a/notes.txt b/notes.txt index a20cb8f..fc63303 100644 --- a/notes.txt +++ b/notes.txt @@ -33,3 +33,37 @@ That is: The hope is the process becomes good at active choice. + + +Ideas for Tenets for a Need-Based Artificial Life +Behavior is Life +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. + + +What is a full intellect? + A full intellect can both keep something constant in a diverse, changing environment, + and design and build something that functions as well as it does, without access to its own workings. + +What is an intellect? + An intellect is something that keep something constant in a diverse, changing environment, + so long as the environment changes slowly enough for the intellect to learn to adapt to it. + +What basic parts do we expect a full intellect to have? +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 +meaning representation: the ability to store and work with conceptual information +relevence: the ability to apply concepts and actions more in contexts they are likely to be useful than those they aren't +self-modification: at least part of the system must be fully alterable by the system and generic enough to replace it. <- due to danger, must include controversial needs in decisions -- cgit v1.2.3 From 099cc702a91c9736b1fa08b76de8db1346f438f5 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Tue, 22 Oct 2019 09:19:27 -0400 Subject: notes --- notes.txt | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/notes.txt b/notes.txt index fc63303..5a176bf 100644 --- a/notes.txt +++ b/notes.txt @@ -52,18 +52,43 @@ 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. - -What is a full intellect? - A full intellect can both keep something constant in a diverse, changing environment, - and design and build something that functions as well as it does, without access to its own workings. - +Proposed Definitions: What is an intellect? - An intellect is something that keep something constant in a diverse, changing environment, - so long as the environment changes slowly enough for the intellect to learn to adapt to it. + 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? -brainstorming/trial-and-error: the ability to try or consider different things and find ones that work well +- Trial Exploration +- Relevence +- Self Coding +- Pattern Generality +- Meaning Representation +- Promise Meeting + +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 -meaning representation: the ability to store and work with conceptual information -relevence: the ability to apply concepts and actions more in contexts they are likely to be useful than those they aren't -self-modification: at least part of the system must be fully alterable by the system and generic enough to replace it. <- due to danger, must include controversial needs in decisions + +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 + +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. + + +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. + -- cgit v1.2.3 From c380a164a173b5c8cb7efa0ef271824faf1a7534 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Tue, 22 Oct 2019 13:04:23 -0400 Subject: approach change --- nascent6.js | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 nascent6.js diff --git a/nascent6.js b/nascent6.js new file mode 100644 index 0000000..d7241ba --- /dev/null +++ b/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 +// run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. +// -- cgit v1.2.3 From 499c60eec056b9e1cf85caaab7b70a93ea1081ad Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Wed, 23 Oct 2019 08:35:13 -0400 Subject: whatever notes changes there are --- notes.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/notes.txt b/notes.txt index 5a176bf..18a8f21 100644 --- a/notes.txt +++ b/notes.txt @@ -68,6 +68,9 @@ What basic parts do we expect a full intellect to have? - 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 @@ -76,6 +79,8 @@ 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. -- cgit v1.2.3 From bf6ac49baabdc53f347715394210152466a0ee7c Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Wed, 23 Oct 2019 08:36:13 -0400 Subject: moved into subdir for merge --- README.md | 35 ---- nascent1.js | 107 ----------- nascent2.js | 172 ------------------ nascent3.js | 199 -------------------- nascent4.js | 242 ------------------------- nascent5.js | 382 --------------------------------------- nascent6.js | 461 ----------------------------------------------- notes.txt | 99 ---------- starts/bagel/README.md | 35 ++++ starts/bagel/nascent1.js | 107 +++++++++++ starts/bagel/nascent2.js | 172 ++++++++++++++++++ starts/bagel/nascent3.js | 199 ++++++++++++++++++++ starts/bagel/nascent4.js | 242 +++++++++++++++++++++++++ starts/bagel/nascent5.js | 382 +++++++++++++++++++++++++++++++++++++++ starts/bagel/nascent6.js | 461 +++++++++++++++++++++++++++++++++++++++++++++++ starts/bagel/notes.txt | 99 ++++++++++ 16 files changed, 1697 insertions(+), 1697 deletions(-) delete mode 100644 README.md delete mode 100644 nascent1.js delete mode 100644 nascent2.js delete mode 100644 nascent3.js delete mode 100644 nascent4.js delete mode 100644 nascent5.js delete mode 100644 nascent6.js delete mode 100644 notes.txt create mode 100644 starts/bagel/README.md create mode 100644 starts/bagel/nascent1.js create mode 100644 starts/bagel/nascent2.js create mode 100644 starts/bagel/nascent3.js create mode 100644 starts/bagel/nascent4.js create mode 100644 starts/bagel/nascent5.js create mode 100644 starts/bagel/nascent6.js create mode 100644 starts/bagel/notes.txt diff --git a/README.md b/README.md deleted file mode 100644 index 9996ce9..0000000 --- a/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# 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/nascent1.js b/nascent1.js deleted file mode 100644 index b6b5552..0000000 --- a/nascent1.js +++ /dev/null @@ -1,107 +0,0 @@ -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/nascent2.js b/nascent2.js deleted file mode 100644 index 883aa7a..0000000 --- a/nascent2.js +++ /dev/null @@ -1,172 +0,0 @@ -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/nascent3.js b/nascent3.js deleted file mode 100644 index 0a6c4a3..0000000 --- a/nascent3.js +++ /dev/null @@ -1,199 +0,0 @@ -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/nascent4.js b/nascent4.js deleted file mode 100644 index 093df79..0000000 --- a/nascent4.js +++ /dev/null @@ -1,242 +0,0 @@ -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/nascent5.js b/nascent5.js deleted file mode 100644 index 1d9e8ae..0000000 --- a/nascent5.js +++ /dev/null @@ -1,382 +0,0 @@ -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 -// 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/nascent6.js b/nascent6.js deleted file mode 100644 index d7241ba..0000000 --- a/nascent6.js +++ /dev/null @@ -1,461 +0,0 @@ -// 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 -// 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/notes.txt b/notes.txt deleted file mode 100644 index 18a8f21..0000000 --- a/notes.txt +++ /dev/null @@ -1,99 +0,0 @@ -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 -Behavior is Life -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. - - -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. - 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 +// 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 +// 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 +Behavior is Life +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. + + +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. + -- cgit v1.2.3 From 30226c76aa10eeabf77ad9b9a996b8fbb0934c64 Mon Sep 17 00:00:00 2001 From: Karl Semich Date: Wed, 23 Oct 2019 08:37:24 -0400 Subject: add note --- BAGEL.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 BAGEL.md diff --git a/BAGEL.md b/BAGEL.md new file mode 100644 index 0000000..0b4fe90 --- /dev/null +++ b/BAGEL.md @@ -0,0 +1 @@ +Bagel has moved into starts/bagel in the intellect repository owned by xloem. -- cgit v1.2.3