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