diff options
Diffstat (limited to 'starts')
-rw-r--r-- | starts/bagel/README.md | 35 | ||||
-rw-r--r-- | starts/bagel/nascent1.js | 107 | ||||
-rw-r--r-- | starts/bagel/nascent2.js | 172 | ||||
-rw-r--r-- | starts/bagel/nascent3.js | 199 | ||||
-rw-r--r-- | starts/bagel/nascent4.js | 242 | ||||
-rw-r--r-- | starts/bagel/nascent5.js | 382 | ||||
-rw-r--r-- | starts/bagel/nascent6.js | 461 | ||||
-rw-r--r-- | starts/bagel/notes.txt | 99 |
8 files changed, 1697 insertions, 0 deletions
diff --git a/starts/bagel/README.md b/starts/bagel/README.md new file mode 100644 index 0000000..9996ce9 --- /dev/null +++ b/starts/bagel/README.md @@ -0,0 +1,35 @@ +# bagel +well really it's a little hobby sentient-AI idea, but it's too small to do or be anything + +# relevence +The idea is kind of that our minds have a very fancy network of nearness and farness of concepts. +When I think about something -- brainstorm on it -- my mind activates it and it activates relevent associated thoughts. +It pours through different thoughts that are nearby by association, and keeps the ones that are more useful, more relevent, while +discarding the ones that aren't. + +# self-reference +Additionally, my mind when working on a task, can improve the actual process of working on the task. The steps can change. +The process for finding steps can change. The whole goal can change. I can even go out and wonder why I am working the task +in the first place, and think about that. Then I can act on the new decision. +By making code that writes itself, we move towards an intellect that can learn and improve. + +# implementation ideas +I wrote out some quick relevence around how I might write code, and it seemed like the 'why' for each step was basically a small +chunk of code itself. It seems like there are relevent concepts in my mind that are roughly linked to these small behaviors +(habits or chunks of code). By making such links in actual code, the code looks more mindlike to me. +One of the keys is to get the code to make the links itself, and I think what is important there is the concept of patterns-that- +work. If you can discern when code works, then you can look for similar properties on the before and end states. If some of them +are always the same when it works, those are probably the ones that should be linked to the code chunk under study. This provides +for rudimentary learning. + +# size +This code is written very tiny so that little work need be invested in it for it have conceptual growth. The idea and hope somehow +is that it move rapidly towards coding itself, such that as it gets coded, the developer need do less to work on it, being able to +instead make use of its internal functions for producing code-like behavior. + +# language +By prototyping in a flexible language like Javascript, design work may be hastened a little. I also theorize that a good AI doesn't +need many cpu cycles to get stuff done, because it makes smart choices. + +# etc +There is of course more. This writing content was made day-of-creation. Will I ever edit this again? Unknown. diff --git a/starts/bagel/nascent1.js b/starts/bagel/nascent1.js new file mode 100644 index 0000000..b6b5552 --- /dev/null +++ b/starts/bagel/nascent1.js @@ -0,0 +1,107 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(item) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + this.ram.push(item) + } + del(item) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + contains(item) { + for (let a of this.ram) + if (a == item) return a + return false + } + containsWith(prop, val) { + let ret = [] + for (let a of this.ram) + if (a[prop] == val) + return true + return false + } + getWith(prop, val) { + let ret = [] + //console.log('get-with ' + prop + ' ' + val) + for (let a of this.ram) { + //console.log(a + ' ' + prop + ' is ' + a[prop]) + if (a[prop] == val) + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} + +function sayhi() { + res = 'hi' + res.use = 'output' + console.log(res) + return 'said ' + res +} +sayhi.relevence = function(ram) { + return [ram.ram[0]]; +} + +function line2words(line) { + let res = line.split(' ') + res.type = 'list' + return res +} +line2words.relevence = function(ram) { + return ram.getWith('type', 'text') +} + +all_parts = [ line2words, sayhi ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new String(line) + line.use = 'input' + line.type = 'text' + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part(a) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + //if (rel) { + // let ram2 = ram.clone() + // for + //} + } + } while (cont) +}) diff --git a/starts/bagel/nascent2.js b/starts/bagel/nascent2.js new file mode 100644 index 0000000..883aa7a --- /dev/null +++ b/starts/bagel/nascent2.js @@ -0,0 +1,172 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Set(from && from.props) + this.add('string') + this.del('array') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Set(from && from.props) + this.add('array') + this.del('string') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} + +function line2words(line) { + let res = new ArrayData(line.split(' '), line) + res.add('words') + return res +} +line2words.relevence = function(ram) { + return ram.getWith('text', 'string') +} +line2words.makes = ['array','words'] // property values produced + +function respondhello(words) { + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.add('output') + res.add('text') + return res +} +respondhello.relevence = function(ram) { + let res = ram.getWith('words', 'input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res +} +respondhello.makes = ['output'] + +// nodejs is missing a succinct read-line-from-stdin function. here, we make one. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + function userinput() { + let res = new StringData(lines.shift()) + res.add('text') + res.add('input') + return res + } + userinput.relevence = function() { + return lines.length > 0 + } + userinput.makes = ['string','text','input'] + + return userinput +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.add('input') + line.add('text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent3.js b/starts/bagel/nascent3.js new file mode 100644 index 0000000..0a6c4a3 --- /dev/null +++ b/starts/bagel/nascent3.js @@ -0,0 +1,199 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let b of props) + if (! a.has(b)) + continue outer + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Set(from && from.props) + this.add('string') + this.del('array') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Set(from && from.props) + this.add('array') + this.del('string') + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} +class FunctionData { + constructor(name, func, relevence, makes) { + this.name = name + this.props = new Set() + this.props.add('function') + this.props.add(name) + this.call = func + this.relevence = relevence + this.makes = makes + } + add(val) { + this.props.add(val) + } + has(val) { + return this.props.has(val) + } + del(val) { + this.props.delete(val) + } +} + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.add('words') + return res + }, + (ram) => { // relevence + return ram.getWith('text', 'string') + }, + ['array','words'] // makes +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.add('output') + res.add('text') + return res + }, + (ram) => { // relevence + let res = ram.getWith('words', 'input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res + }, + ['output', 'text'] // makes +) + +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + return new FunctionData( + 'userinput', + () => { // call + let res = new StringData(lines.shift()) + res.add('text') + res.add('input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['string','text','input'] // makes + ) +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.add('input') + line.add('text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent4.js b/starts/bagel/nascent4.js new file mode 100644 index 0000000..093df79 --- /dev/null +++ b/starts/bagel/nascent4.js @@ -0,0 +1,242 @@ +class ActiveMemory { + constructor() { + this.ram = [] + this.cloned = false + } + clone() { + let ret = new ActiveMemory(); + ret.ram = this.ram + ret.cloned = true + return ret + } + add(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) + this.ram.push(item) + } + del(...items) { + if (this.cloned) { this.ram = this.ram.slice(); this.cloned = false; } + for (let item of items) { + let index = this.ram.indexOf(item) + this.ram.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.ram.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this.ram) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + has(type, dest) { + for (let p of this.props) + if (p.type == type && p.dest == dest) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} +class FunctionData { + constructor(name, func, relevence, makes) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + this.relevence = relevence + this.makes = makes + } +} + +// variables: +// - create a place to store a value +// createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.add +// let name = obj_and_name[1] +// }, +// /*relevence*/, +// /*makes*/ +// ) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + return res + }, + (ram) => { // relevence + return ram.getWith('is','text', 'is','string') + }, + ['is','array','is','words'] // makes +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + ", user!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + (ram) => { // relevence + let res = ram.getWith('is','words', 'is','input') + if (res) res = res.filter(x => { x = x[0].toLowerCase(); return x == 'hello' || x == 'hi'}) + return res + }, + ['is','output', 'is','text'] // makes +) + +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + return new FunctionData( + 'userinput', + () => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['is','string','is','text','is','input'] // makes + ) +})() + + +all_parts = [ line2words, respondhello ] + +ram = new ActiveMemory() +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + let rel = part.relevence(ram) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + optstried.add(part.name + ' ' + a) + + } + } + } + } while (cont) +}) diff --git a/starts/bagel/nascent5.js b/starts/bagel/nascent5.js new file mode 100644 index 0000000..1d9e8ae --- /dev/null +++ b/starts/bagel/nascent5.js @@ -0,0 +1,382 @@ +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + has(type, dest) { + for (let p of this.props) + if ((p.type == type || isVar(type)) + && (p.dest == dest || isVar(dest))) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } + hasIsVar() { + return this.has('is','variable') + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} + +// Abstractions? +const VAR_X = new StringData('X') +VAR_X.props.add('is','variable') +// recommend e.g. 'is','variable-rep' when code is designing them, so don't match everything +function isVar(x) { + return x.props && x.props.has('is','variable') +} + +// MEMORY +// the archivist. Provides for needs of data. Memory is relevent whenever there is +// an informational need. +// +// When remembering steps, likely what is relevent is what is needed to reach the goal +// Here's a possible step memory. +// +// let ret = new StringData('labeled ' + items.length + ' text-string') +// ret.props.add('is','step-memory') +// ret.props.add('step',genproptextstring) +// ret.props.add('ram',ram) +// ret.props.add('count',items.length) +// for (let a of items) +// ret.props.add('item', a) + +class ActiveMemory extends ArrayData { + // although Memory is eventually a module that provides for stored information needs + // this class is just a group of concepts, moved in and out as needed + constructor(items, from) { + super(items || [], from) + this.props.add('is','working-ram') + } + clone() { + return new ActiveMemory(this, this); + } + add(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) + this.push(item) + } + del(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) { + let index = this.indexOf(item) + this.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +// note: for now we produce only data; state-changes are data-changes +class FunctionData { + constructor(name, // name of function + func, // function taking ordered needs + // ordered array of made objects is returned + needs, // array of 1-property-per-object this function requires + makes // array of 1-property-per-object this function produces + ) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + // If needed, make atomspace-like pattern structures for needs/makes. + // - represent multiple properties on 1 needed object + // - represent input objects present in output + this.needs = needs + this.makes = makes + } +} + +// variables: +// - create a place to store a value +//createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.props.add('is','varspec') +// return ret +// }, +// /*relevence*/, +//// when do you want to create a variable? when you need a variable and you have a name +// /*makes*/ +//) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: (these are like promises of what to do and how to use something) +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + res.props.del('is','text-string') + return res + }, + ['is','text-string'], // needs + ['is','word-array'] // makes +) + +// makes text-string used by line2words. example of small relevence habit +genproptextstring = new FunctionData( + 'genproptextstring', + /*call*/(text) => { + if (text.props.has('is','string')) { + if (!text.props.has('is','text-string')) { + text.props.add('is','text-string') + } + return text + } + return null + }, + /*needs*/['is','text'], + /*makes*/['is','text-string'] +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + " world!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + ['is','hello-input'], // needs + ['is','output'] // makes +) + +genprophelloinput = new FunctionData( + 'genprophelloinput', + /*call*/(input) => { + if (!input.props.has('is','words')) + return null + if (!input.props.has('is','hello-input')) { + let x = input[0].toLowerCase() + let c = x[x.length-1] + if (c == ',' || c == '!' || c == '.') x = x.slice(0,x.length-1) + if (x != 'hello' && x != 'hi') return null + input.props.add('is','hello-input') + } + return input + }, + /*needs*/['is','input'], + /*makes*/['is','hello-input'] +) + +/* old, this isn't relevent to needed structure +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + let ret = new FunctionData( + 'userinput', + (self) => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['has','userinput-lines'] // needs + ['is','string','is','text','is','input'] // makes + ) + ret.lines = lines +})() +genprophaslines = new FunctionData( + 'genprophaslines', + (userinput) => { // call + } +) +*/ + +// PATTERN REQUEST: we want to be able to store needed-steps. +// needed-steps are parallel needs that are needed for a helpful step +// any one may be met, and others are ignored once one is, but all are generated at once +// habits that meet needs expect them not to be inside an array and have no way of referring to that. +// [AND needs can be collapsed, but OR needs need patterns] +// [how do we pull a need out of the list?] + +// make a habit that plans core behavior +// for some other ideas, see this function in nascent6.js +findstepsfor = new FunctionData( + 'findstepsfor', + /*call*/(need, depth) => { + // find a habit that does the final goal. + // TODO: for now we assume all needs are 'is' and store just what-it-is in the need string. when doesn't work anymore, make type-getters on Properties to retrieve the need details + let ret = new ArrayData([]) + for (let habit of all_parts) { + if (habit.makes.indexOf(need) !== -1) { + // found a workable habit + ret.push(habit.needs) + } + } + ret.props.add('is','alternate-needs-array') + return ret + }, + // TODO: likely need more structure here + /*needs*/['is','desired-need'], + /*makes*/['is','alternate-needs-array'] +) + +// TODO: add structure enough to build findstepsfor +// TODO: build findstepsfor +// TODO 2: add to surrounding process: remove source needs when there is no longer a reason for their presence + + +all_parts = [ line2words, genproptextstring, respondhello, genprophelloinput ] + +ram = new ActiveMemory() +//ram.add(ram) +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + // TODO: >1 parameter,must redo next line + let rel = ram.getWith(...part.needs) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + optstried.add(part.name + ' ' + a) + if (res == null) continue + // TODO: res==null is considered failure now + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + } + } + } + } while (cont) +}) + + +// it looks like there is a reason to store each item in active memory. +// one reason is that it is needed by a step in a process. +// when there are no reasons, it is removed. +// using an item should link it to what it is used by, so that it may be found easier again when needed + +// Please grow to understand your own structure. What is needed to make an intellect? +// ^-- we want it to learn the basic needs of life, eventually, on its own. +// notably those to do with care for others. + +// MEMORY: see MEMORY above + +// RELEVENCE: the gofer. Provides the link between needs, etc, and the behavior that +// finds them. Is relevent for meeting needs in active ways and likely much else. + +// BEHAVIOR: the core. combines interdependent habits from memory to meet needs. +// The two below go on simultaneously. only 1 is needed. +// A way to plan behavior: +// find habits that do the final goal, discern their needs +// pick needs to treat as a new final goal and repeat until needs are met +// A way to make behavior: +// find a habit that does a goal +// find with this process, information that meets its needs <spawns more> +// run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. +// diff --git a/starts/bagel/nascent6.js b/starts/bagel/nascent6.js new file mode 100644 index 0000000..d7241ba --- /dev/null +++ b/starts/bagel/nascent6.js @@ -0,0 +1,461 @@ +// This file was WIP, two prongs were being pursued at once when work was halted. + +// Meaning Representation +class Property { + constructor(type, dest) { + this.type = type + this.dest = dest + } +} +class Properties { + // members are all Usage Simplification defining Promise Spec + constructor(type, from) { + this.props = from ? from.props.slice() : [] + //if (from) {console.log('INHERIT: '); for (let prop of this.props) { console.log(prop) }} + this.add('is', type) + } + toString() { + let str = '' + for (let prop of this.props) { + str += prop.type + ':' + prop.dest + ' ' + } + return str + } + add(type, dest) { + this.props.push(new Property(type, dest)) + } + // recommend hoisting variables when designing them, so they don't match everything + has(type, dest) { + for (let p of this.props) + if ((p.type == type || isVar(type)) + && (p.dest == dest || isVar(dest))) + return true + return false + } + del(type, dest) { + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type && p.dest == dest) { + this.props.splice(i, 1) + return true + } + } + return false + } + get(type) { + let result = null + for (let i = 0; i < this.props.length; ++ i) { + let p = this.props[i] + if (p.type == type) { + if (result) throw new Error('get on multiply defined property') + result = p.dest + } + } + return result + } + hasIsVar() { + return this.has('is','variable') + } +} +class AbstractData { + constructor(from) { + this.props = new Properties('abstract', from && from.props) + } +} +class StringData extends String { + constructor(str, from) { + super(str) + this.props = new Properties('string', from && from.props) + this.props.del('is', 'array') + } +} +class ArrayData extends Array { + constructor(arr, from) { + super(...arr) + this.props = new Properties('array', from && from.props) + this.props.del('is', 'string') + } +} + +// Meaning Representation +class Var extends StringData { + constructor(name){ + super(name) + props.add('is','variable') + } + // recommend e.g. 'is','variable-rep' when code is designing them, so don't match everything + // opencog uses a 'quote' wrapper to cause this, sounds more general +} +function isVar(x) { + return x.props && x.props.has('is','variable') +} +const ONE = StringData('one') +const MANY = StringData('many') +const VAR_X = new Var('X') + +// MEMORY +// the archivist. Provides for needs of data. Memory is relevent whenever there is +// an informational need. +// +// When remembering steps, likely what is relevent is what is needed to reach the goal +// Here's a possible step memory. +// +// let ret = new StringData('labeled ' + items.length + ' text-string') +// ret.props.add('is','step-memory') +// ret.props.add('step',genproptextstring) +// ret.props.add('ram',ram) +// ret.props.add('count',items.length) +// for (let a of items) +// ret.props.add('item', a) + +class ActiveMemory extends ArrayData { + // although Memory is eventually a module that provides for stored information needs + // this class is just a group of concepts, moved in and out as needed + constructor(items, from) { + super(items || [], from) + this.props.add('is','working-ram') + } + clone() { + return new ActiveMemory(this, this); + } + add(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) + this.push(item) + } + del(...items) { + //if (this.cloned) { this = this.slice(); this.cloned = false; } + for (let item of items) { + let index = this.indexOf(item) + this.splice(index, 1) + } + } + contains(...items) { + for (let item of items) + if (this.indexOf(item) === -1) return false + return true + } + containsWith(...props) { + let ret = [] + outer: for (let a of this) { + for (let i = 0; i < props.length; i += 2) + if (! a.props.has(props[i], props[i+1])) + continue outer + return true + } + return false + } + getWith(...props) { + let ret = [] + outer: for (let a of this) { + //console.log(a.props.props) + for (let i = 0; i < props.length; i += 2) { + //console.log(props[i] + ': ' + props[i+1] + '?') + if (! a.props.has(props[i], props[i+1])) + continue outer + } + ret.push(a) + } + if (ret.length > 0) return ret + return null + } +} +// note: for now we produce only data; state-changes are data-changes +// TODO: this class has methods. turn them into promise-meeting-habits. a promise is a spec for behavior, e.g. how data is stored. this spec can be interpeted by a more general habit. +class FunctionData { + constructor(name, // name of function + func, // function taking ordered needs + // ordered array of made objects is returned + needs, // array of 1-property-per-object this function requires + makes // array of 1-property-per-object this function produces + ) { + this.name = name + this.props = new Properties('function') + this.props.add('name', name) + this.call = func + // If needed, make atomspace-like pattern structures for needs/makes. + // - represent multiple properties on 1 needed object + // - represent input objects present in output + this.needs = needs + this.makes = makes + } + makesFrom(ram) { // what we make with the ram + // match needs + + // TODO: improve from just picking 1. preferably with relevence. + for (let i = 0; i < this.needs.length; i += 2) { + if (isVar(this.needs[i]) || isVar(this.needs[i+1])) { + // iterate all other options with this? just pick 1? + // STUB + } else { + if (!ram.containsWith(this.needs[i], this.needs[i+1])) + return [] + } + } + // fill variables STUB + } + // say I want would-meet apple + // and I have needs apple + // the easiest way to find this is to fill the needs in with what I have +} + +// variables: +// - create a place to store a value +//createvar = new FunctionData( +// 'createvar', +// /*call*/(name) => { +// let ret = new StringData(name) +// ret.props.add('is','varspec') +// return ret +// }, +// /*relevence*/, +//// when do you want to create a variable? when you need a variable and you have a name +// /*makes*/ +//) +// - place a value in such a place +// - retrieve a value from such a place +// data-structures: (these are like promises of what to do and how to use something) +// - make a class definition (collection of variables) +// - initialize an object +// - set/retrieve properties (variables) +// flow: +// - trigger a different step than the next, conditionally +// procedures: +// - collect a set of behaviors together +// - trigger a collected set of behaviors and continue +// expressions: +// - evaluate arithmetic on variables and constants + +// sometimes how we get what we need depends on what we have +line2words = new FunctionData( + 'line2words', + (line) => { // call + let res = new ArrayData(line.split(' '), line) + res.props.add('is','words') + res.props.del('is','text-string') + return res + }, + ['is','text-string'], // needs + ['is','word-array'] // makes +) + +// makes text-string used by line2words. example of small relevence habit +genproptextstring = new FunctionData( + 'genproptextstring', + /*call*/(text) => { + if (text.props.has('is','string')) { + if (!text.props.has('is','text-string')) { + text.props.add('is','text-string') + } + return text + } + return null + }, + /*needs*/['is','text'], + /*makes*/['is','text-string'] +) + +respondhello = new FunctionData( + 'respondhello', + (words) => { // call + console.log(words[0] + " world!") + let res = new StringData("said " + words[0]) + res.props.add('is','output') + res.props.add('is','text') + return res + }, + ['is','hello-input'], // needs + ['is','output'] // makes +) + +genprophelloinput = new FunctionData( + 'genprophelloinput', + /*call*/(input) => { + if (!input.props.has('is','words')) + return null + if (!input.props.has('is','hello-input')) { + let x = input[0].toLowerCase() + let c = x[x.length-1] + if (c == ',' || c == '!' || c == '.') x = x.slice(0,x.length-1) + if (x != 'hello' && x != 'hi') return null + input.props.add('is','hello-input') + } + return input + }, + /*needs*/['is','input'], + /*makes*/['is','hello-input'] +) + +/* old, this isn't relevent to needed structure +// nodejs is missing a succinct read-line-from-stdin function. make our own. +userinput = (() => { + const readline = require('readline') + const lines = [] + readline.createInterface({ input: process.stdin }).on('line', (line) => { + lines.push(line) + }) + + let ret = new FunctionData( + 'userinput', + (self) => { // call + let res = new StringData(lines.shift()) + res.props.add('is','text') + res.props.add('is','input') + return res + }, + () => { // relevence + return lines.length > 0 + }, + ['has','userinput-lines'] // needs + ['is','string','is','text','is','input'] // makes + ) + ret.lines = lines +})() +genprophaslines = new FunctionData( + 'genprophaslines', + (userinput) => { // call + } +) +*/ + +// PATTERN REQUEST: we want to be able to store needed-steps. +// needed-steps are parallel needs that are needed for a helpful step +// any one may be met, and others are ignored once one is, but all are generated at once +// habits that meet needs expect them not to be inside an array and have no way of referring to that. +// [AND needs can be collapsed, but OR needs need patterns] +// [how do we pull a need out of the list?] + +// is it useful to use as a need the memory generated by a habit? + +// make a habit that plans core behavior +findstepsfor = new FunctionData( + 'findstepsfor', + /*call*/(need, depth) => { + // find a habit that does the final goal. + // TODO: for now we assume all needs are 'is' and store just what-it-is in the need string. when doesn't work anymore, make type-getters on Properties to retrieve the need details + let ret = new ArrayData([]) + for (let habit of all_parts) { + if (habit.makes.indexOf(need) !== -1) { + // found a workable habit + ret.push(habit.needs) + } + } + ret.props.add('is','alternate-needs-array') + return ret + }, + // TODO: likely need more structure here + // warning: MANY adds surrounding code complexity. please put makes-interpretation in a habit if MANY is used. <- let's just put this in the class constructor for now + /*needs*/['needs', VAR_X], + /*makes*/[MANY, 'would-meet', VAR_X] + // really we are usually met due to the need to meet a goal + // and the need to have steps to meet that particular goal + // how do we write a need that supports another need + // + // propose relevence is a list of reasons each with a strength, and greatest sum is chosen + // HABIT/ACTIVE BEHAVIOR wants relevent-met-habits, to act on + // PLANNING/GOAL BEHAVIOR wants relevent-unmet-needs to backtrace them towards relevent-met-needs + // + // we can meet any need with behavior, but it takes time. + // [we are ignoring most of karl's needs] + // [the reason is that an AI can meet them all] + // AI meets some needs + // AI is ongoing + // therefore we are working on meeting + // ONE: we have a need for actively pursuing relevent needs + // TWO: we need appropriate multitasking + // AI is long term, so would happen after [quickly-]meetable-needs are met. + // + // make popcorn + // need: made-popcorn + // 1. identify that we need unmade popcorn and a microwave + // ^-- made-popcorn is how? we can meet any need with behavior + // what is substep of find-path-to-need + // find path-part-to-need + // + // need: to meet needs + // need: some-need + // makestepsfor makes: some-other-need tagged makes: some-need + // + // when we push some-need we want to stimulate pushing some-other-need. + // + // use a variable as the link target, and use e.g. met-need + // as the link type +) + +// TODO: add structure enough to build findstepsfor +// TODO: build findstepsfor +// TODO 2: add to surrounding process: remove source needs when there is no longer a reason for their presence + + +all_parts = [ line2words, genproptextstring, respondhello, genprophelloinput ] + +ram = new ActiveMemory() +//ram.add(ram) +optstried = new Set() +steps = [] + +var readline = require('readline') +readline.createInterface({ + input: process.stdin +}).on('line', (line) => { + line = new StringData(line) + line.props.add('is','input') + line.props.add('is','text') + ram.add(line) + + let cont + do { + cont = false + for (let part of all_parts) { + //console.log('for-loop-of-parts ' + part.name) + // TODO: >1 parameter,must redo next line + let rel = ram.getWith(...part.needs) + if (rel) { + for (let a of rel) { + //console.log('for-loop-of-rel ' + part.name + ' ' + a) + if (optstried.has(part.name + ' ' + a)) continue; + //console.log('call-part ' + part.name + ' ' + a) + res = part.call(a) + optstried.add(part.name + ' ' + a) + if (res == null) continue + // TODO: res==null is considered failure now + ram.add(res) + //console.log('part-called') + step = [a, part.name, res] + steps.push(step) + console.log('made ' + step) + cont = true + } + } + } + } while (cont) +}) + + +// it looks like there is a reason to store each item in active memory. +// one reason is that it is needed by a step in a process. +// when there are no reasons, it is removed. +// using an item should link it to what it is used by, so that it may be found easier again when needed + +// Please grow to understand your own structure. What is needed to make an intellect? +// ^-- we want it to learn the basic needs of life, eventually, on its own. +// notably those to do with care for others. + +// MEMORY: see MEMORY above + +// RELEVENCE: the gofer. Provides the link between needs, etc, and the behavior that +// finds them. Is relevent for meeting needs in active ways and likely much else. + +// BEHAVIOR: the core. combines interdependent habits from memory to meet needs. +// The two below go on simultaneously. only 1 is needed. +// A way to plan behavior: +// find habits that do the final goal, discern their needs +// pick needs to treat as a new final goal and repeat until needs are met +// A way to make behavior: +// find a habit that does a goal +// find with this process, information that meets its needs <spawns more> +// run it +// TODO: for subprocesses spawning, +// consider labelling things that are very quick and side-effect-free +// these can probably be immediately run. +// diff --git a/starts/bagel/notes.txt b/starts/bagel/notes.txt new file mode 100644 index 0000000..18a8f21 --- /dev/null +++ b/starts/bagel/notes.txt @@ -0,0 +1,99 @@ +The habits should be used to discern what is relevent; to form relevence. +The goal should be to choose a relevent habit and do that habit. + +These are the basic habits I thought up that a computer program has: + variables: + - create a place to store a value + - place a value in such a place + - retrieve a value from such a place + data-structures: + - make a class definition (collection of variables) + - initialize an object + - set/retrieve properties (variables) + flow: + - trigger a different step than the next, conditionally + procedures: + - collect a set of behaviors together + - trigger a collected set of behaviors and continue + expressions: + - evaluate arithmetic on variables and constants + + +That is: +======================================================================================================== + - the active goal is to choose what to do and to what, and do it + - the way to do this is the same as it: + by picking habits that are relevent in the moment [choose what to do], + and running them on relevent data [choose to what, and do it] +======================================================================================================== + - the habits should be to identify what is relevent + + - we have a request for the initial goal of the process to be to write a chunk of code out in its own language + tighter self-reference is made without the extra sourcecode-file step, but it may be slower to code due to not getting as much help from it + +The hope is the process becomes good at active choice. + + + +Ideas for Tenets for a Need-Based Artificial Life <need ordering + addition + code> +Behavior is Life <maybe Life is Behavior That Adapts> +All life has the same core needs. Needs are the reasons to do anything at all. +We need to know what we want when we act. (all behavior has a reason) +We need to be able to learn new things. +We need to be able to make promises on how to behave. (provides for cooperation) +We need to be able to keep our promises. +We need to know how to communicate with others what each of us knows. +We need to freely interact with our friends, our parts, and our community, in ways that we know well. (community is our body) +Information lives with a reason, a purpose. +We need to retain the information we choose to retain. +We need to act to meet our needs. +We need to identify relevent important needs that support our needs. + +We need to be able to try new ways of doing things. +We need to be able to judge what works. + +Proposed Definitions: +What is an intellect? + Propose an intellect is something that can adapt to keep something constant in a diverse, changing environment, + so long as the environment changes slowly enough and with enough familiarity for them to learn or prepare effectively. +What is a full intellect? + Propose that a full intellect is an intellect that can design and build something that functions as well as they do, + without access to their own workings, and is able to learn to handle arbitrarily fast or new diverse environmental change. + +What basic parts do we expect a full intellect to have? +- Trial Exploration +- Relevence +- Self Coding +- Pattern Generality +- Meaning Representation +- Promise Meeting + +What other parts do we find we need? +- Usage Simplification + +Trial Exploration + Brainstorming, trial-and-error. The ability to try or consider different things and find ones that work well. + simple approaches: exhaustive search, and random trial + +Relevence + The ability to apply concepts and actions moreso in contexts they are likely to be useful than those they aren't. + 1. responsiveness for behavior: a habit acts when conditions arise, not when it is 'next' + 2. possibly a promise for decision-making, for proposals to have reasons with associated strengths + (note: strength appears developed from source reasons and can be missing data that can be filled in by habits when needed) + TODO: make relevent decision-making honor convergent needs. maybe strength represents information exchange. + +Self-Coding + At least part of the system must be fully alterable by the system and generic enough to replace it. + Due to the danger involved in this, controversial concerns must be fully included in decisions around it. + Karl references Convergent Facilitation as proof that a decision can be found to satisfy any set of controversial concerns. + <it very roughly involves rapidly moving towards the reasons of the concerns until they don't conflict; there is a lot of caring dialogue> + +Pattern Generality + The ability to brainstorm on enough relationships, possibly mathematical, to discover pattern-summaries that are diversely effective in the real world. + +Meaning Representation + The ability to store and work with conceptual information. + +Promise Meeting + The ability to make agreements on behavior and structure, adhere to them, and change them when needed. + |