theprogrammablemind 7.1.4-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/digraph.js ADDED
@@ -0,0 +1,110 @@
1
+ const toA = (edge) => {
2
+ if (Array.isArray(edge)) {
3
+ return edge
4
+ } else {
5
+ return [edge.child, edge.parent]
6
+ }
7
+ }
8
+
9
+ class Digraph {
10
+ // edges maybe either [child, parent] or { child, parent }
11
+ constructor (edges = []) {
12
+ this.edges = edges
13
+ }
14
+
15
+ /*
16
+ edges () {
17
+ return this.edges
18
+ }
19
+ */
20
+ acdcs (s, from, to) {
21
+ const todo = [s]
22
+ const seen = new Set([s])
23
+ const acdcs = new Set([])
24
+ while (todo.length > 0) {
25
+ const n = todo.pop()
26
+ this.edges.forEach((e) => {
27
+ e = toA(e)
28
+ if (e[from] === n) {
29
+ acdcs.add(e[to])
30
+ if (!seen.has(e[to])) {
31
+ todo.push(e[to])
32
+ seen.add(e[to])
33
+ }
34
+ }
35
+ })
36
+ }
37
+ return acdcs
38
+ }
39
+
40
+ isA (low, high) {
41
+ if (low === high) {
42
+ return true
43
+ }
44
+ return this.ancestors(low).has(high)
45
+ }
46
+
47
+ lessThan (low, high) {
48
+ if (low === high) {
49
+ return false
50
+ }
51
+ return this.ancestors(low).has(high)
52
+ }
53
+
54
+ descendants (s) {
55
+ return this.acdcs(s, 1, 0)
56
+ }
57
+
58
+ ancestors (s) {
59
+ return this.acdcs(s, 0, 1)
60
+ }
61
+
62
+ minima (nodes) {
63
+ let minima = new Set(nodes)
64
+ const ancestors = new Set([])
65
+ nodes.forEach((node) => {
66
+ this.ancestors(node).forEach((n) => ancestors.add(n))
67
+ })
68
+ ancestors.forEach((n) => minima.delete(n))
69
+ if (minima.size === 0) {
70
+ // all unrelated
71
+ minima = new Set(nodes)
72
+ }
73
+ return minima
74
+ }
75
+
76
+ maxima (nodes) {
77
+ const maxima = new Set(nodes)
78
+ const descendants = new Set([])
79
+ nodes.forEach((node) => {
80
+ this.descendants(node).forEach((n) => descendants.add(n))
81
+ })
82
+ descendants.forEach((n) => maxima.delete(n))
83
+ return maxima
84
+ }
85
+
86
+ add (child, parent) {
87
+ this.edges.push([child, parent])
88
+ }
89
+
90
+ addList (l) {
91
+ for (let i = 1; i < l.length; ++i) {
92
+ this.edges.push([l[i - 1], l[i]])
93
+ }
94
+ }
95
+
96
+ order (todo) {
97
+ const ordered = []
98
+ while (todo.length > 0) {
99
+ const nodes = this.minima(todo)
100
+ todo = todo.filter((e) => !nodes.has(e))
101
+ for (const node of nodes) {
102
+ ordered.push(node)
103
+ }
104
+ // ordered = ordered.concat([...nodes])
105
+ }
106
+ return ordered
107
+ }
108
+ }
109
+
110
+ module.exports = Digraph
package/src/flatten.js ADDED
@@ -0,0 +1,143 @@
1
+ const { isArray, isObject, isCompound } = require('./helpers')
2
+ const _ = require('lodash')
3
+
4
+ const DEBUG = (...args) => {
5
+ // DEBUG(...args)
6
+ }
7
+
8
+ const flattens = (markers, contexts) => {
9
+ let flats = []
10
+ for (const context of contexts) {
11
+ // const [more, _] = flatten(markers, context)
12
+ const more = flatten(markers, context)[0]
13
+ flats = flats.concat(more)
14
+ }
15
+ return flats
16
+ }
17
+
18
+ const accumulate = (accumulator, nexts) => {
19
+ const accumulatorPrime = []
20
+ for (const current of accumulator) {
21
+ for (const next of nexts) {
22
+ const nextCurrent = _.clone(current)
23
+ nextCurrent.push(next)
24
+ accumulatorPrime.push(nextCurrent)
25
+ }
26
+ }
27
+ return accumulatorPrime
28
+ }
29
+
30
+ const cartesianHelper = (accumulator, b, ...c) => {
31
+ if (b) {
32
+ return cartesianHelper(accumulate(accumulator, b), ...c)
33
+ } else {
34
+ return accumulator
35
+ }
36
+ }
37
+
38
+ const cartesian = (...factors) => {
39
+ return cartesianHelper([[]], ...factors)
40
+ }
41
+
42
+ const zip = (a1, a2) => {
43
+ return a1.map(function (value, index) {
44
+ return [value, a2[index]]
45
+ })
46
+ }
47
+
48
+ const flattenListHelper = (markers, values) => {
49
+ const flats = []
50
+ let wasFlattened = false
51
+ let singles = []
52
+ for (const value of values) {
53
+ if (!isCompound(value)) {
54
+ singles.push(value)
55
+ } else {
56
+ const [more, wf] = flatten(markers, value)
57
+ if (wf) {
58
+ wasFlattened = wasFlattened || wf
59
+ flats.push(more)
60
+ } else {
61
+ singles = singles.concat(more)
62
+ }
63
+ }
64
+ }
65
+
66
+ // product does weirdness with only choice
67
+ if (!wasFlattened) {
68
+ return [[singles], wasFlattened]
69
+ } else {
70
+ const results = []
71
+ for (const flat of cartesian(...flats)) {
72
+ results.push(singles.concat(flat))
73
+ }
74
+ return [results, wasFlattened]
75
+ }
76
+ }
77
+
78
+ // returns (list, wasFlattened)
79
+ const flatten = (markers, value) => {
80
+ if (isArray(value)) {
81
+ return flattenListHelper(markers, value)
82
+ }
83
+
84
+ const marker = value.marker
85
+ let properties = value
86
+
87
+ // if you want to pull up conj properties fix this to do to the other part
88
+ // split = marker in markers
89
+ const split = markers.includes(marker)
90
+ if (split) {
91
+ if ('value' in properties) {
92
+ return [properties.value, true]
93
+ } else {
94
+ return [[value], false]
95
+ }
96
+ }
97
+
98
+ const keys = []
99
+ const valuess = []
100
+ const unchanged = {}
101
+ DEBUG('properties', JSON.stringify(properties, null, 2))
102
+ for (const key in properties) {
103
+ let wf = false
104
+ let values
105
+ // if isinstance(properties[key], Context) {
106
+ if (isObject(properties[key])) {
107
+ const context = properties[key];
108
+ [values, wf] = flatten(markers, context)
109
+ // } else if (isinstance(properties[key], list)) {
110
+ } else if (isArray(properties[key])) {
111
+ [values, wf] = flattenListHelper(markers, properties[key])
112
+ } else {
113
+ values = [properties[key]]
114
+ }
115
+
116
+ if (wf) {
117
+ keys.push(key)
118
+ valuess.push(values)
119
+ } else {
120
+ unchanged[key] = values[0]
121
+ }
122
+ }
123
+
124
+ const propertiess = []
125
+ DEBUG('-----------> valuess', JSON.stringify(valuess))
126
+ DEBUG('-----------> cartesian(valuess)', JSON.stringify(cartesian(valuess)))
127
+ // for (let values of itertools.product(*valuess)) {
128
+ const cp = cartesian(...valuess)
129
+ DEBUG('-----------> cp', JSON.stringify(cp))
130
+ for (const values of cartesian(...valuess)) {
131
+ // properties = copy.deepcopy(unchanged)
132
+ properties = _.cloneDeep(unchanged)
133
+ // for key, value in zip(keys, values) {
134
+ for (const [key, value] of zip(keys, values)) {
135
+ properties[key] = value
136
+ }
137
+ propertiess.push(properties)
138
+ }
139
+
140
+ return [propertiess, valuess.length > 0]
141
+ }
142
+
143
+ module.exports = { flattens, flatten, cartesian, accumulate }
@@ -0,0 +1,282 @@
1
+ const { args: contextArgs, normalizeGenerator } = require('./helpers')
2
+ const Lines = require('../lines')
3
+ const sortJson = require('sort-json')
4
+ const helpers = require('./helpers')
5
+
6
+ class Generator {
7
+ // constructor ({ match, apply, uuid, index, km, priority, notes }) {
8
+ constructor (generator) {
9
+ generator = normalizeGenerator(generator)
10
+ const { match, apply, uuid, index, km, priority, where, notes, debug } = generator
11
+ this.match = match
12
+ this._apply = apply
13
+ this.uuid = uuid
14
+ this.index = index
15
+ this.km = km
16
+ this.priority = priority || 0
17
+ this.notes = notes
18
+ this.where = where
19
+ this.callId = debug
20
+ }
21
+
22
+ getAPI (config) {
23
+ if (config && config.getAPI) {
24
+ return config.getAPI(this.uuid)
25
+ }
26
+ }
27
+
28
+ getAPIs (config) {
29
+ if (config && config._api && config._api.multiApi) {
30
+ return config._api.apis
31
+ }
32
+ }
33
+
34
+ toLabel () {
35
+ const where = this.where ? `where: "${this.where}"` : ''
36
+ if (!this.km) {
37
+ return where
38
+ }
39
+ return `KM '${this.km}' ordinal: ${this.index} ${where}`
40
+ }
41
+
42
+ toString () {
43
+ return `Generator(${this.match}, ${this._apply})`
44
+ }
45
+
46
+ matches (baseArgs, objects, context, hierarchy, config, options = {}) {
47
+ if (objects && objects.namespaced) {
48
+ objects = objects.namespaced[this.uuid]
49
+ }
50
+ // return this.match({ ...args, args: contextArgs(context, hierarchy), objects, global: objects, hierarchy, context, api: this.getAPI(config) })
51
+ const callId = baseArgs.calls.current()
52
+ const moreArgs = {
53
+ uuid: this.uuid,
54
+ args: contextArgs(context, hierarchy),
55
+ objects,
56
+ global: objects,
57
+ // hierarchy,
58
+ context,
59
+ callId,
60
+ api: this.getAPI(config),
61
+ apis: this.getAPIs(config)
62
+ }
63
+ const args = Object.assign({}, baseArgs, moreArgs)
64
+ // return this.match(args)
65
+ const matches = this.match(args)
66
+ if ((matches && (options.debug || {}).match)
67
+ ||
68
+ callId == this.callId) {
69
+ debugger; // next line is the matcher
70
+ this.match(args)
71
+ }
72
+ return matches
73
+ }
74
+
75
+ apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
76
+ if (!log) {
77
+ throw 'generators.apply argument log is required'
78
+ }
79
+
80
+ // this.getAPI(config)
81
+ let n = (id) => id
82
+ if (config && 'nsToString' in config) {
83
+ n = (id) => config.nsToString(id)
84
+ }
85
+ if (objects && objects.namespaced) {
86
+ objects = objects.namespaced[this.uuid]
87
+ }
88
+ const km = (name) => config.getConfig(name)
89
+ const callId = baseArgs.calls.current()
90
+ const moreArgs = {
91
+ callId,
92
+ uuid: this.uuid,
93
+ // km,
94
+ args: contextArgs(context, hierarchy),
95
+ objects,
96
+ log,
97
+ global:
98
+ objects,
99
+ g,
100
+ n,
101
+ hierarchy,
102
+ context,
103
+ uuid: this.uuid,
104
+ gs,
105
+ config,
106
+ response,
107
+ api: this.getAPI(config),
108
+ apis: this.getAPIs(config)
109
+ }
110
+ const args = Object.assign({}, baseArgs, moreArgs)
111
+ // if (this.callId) {
112
+ // greg
113
+ /*
114
+ if (callId == 'call11' && this.callId) {
115
+ debugger;
116
+ }
117
+ */
118
+ if ((options.debug || {}).apply
119
+ ||
120
+ callId == this.callId) {
121
+ debugger
122
+ }
123
+ return this._apply(args)
124
+ }
125
+ }
126
+
127
+ class Generators {
128
+ constructor (generators, logs = []) {
129
+ generators = (generators || []).map((generator) => {
130
+ if (generator instanceof Generator) {
131
+ return generator
132
+ } else {
133
+ return new Generator(generator)
134
+ }
135
+ })
136
+ this.defaults = []
137
+ const priorityToGenerators = {}
138
+ const add = (priority, value) => {
139
+ if (!priorityToGenerators[priority]) {
140
+ priorityToGenerators[priority] = []
141
+ }
142
+ priorityToGenerators[priority].push(value)
143
+ }
144
+ for (const generator of generators) {
145
+ const priority = generator.priority
146
+ add(priority, generator)
147
+ }
148
+ this.generators = []
149
+ for (const key of Object.keys(priorityToGenerators).sort()) {
150
+ this.generators = this.generators.concat(priorityToGenerators[key])
151
+ }
152
+ // this.generators = generators
153
+ this.logs = logs
154
+ };
155
+
156
+ // assumed - properties added to contexts before the generators are called. For setting paraphrase property
157
+ apply (args, contexts, assumed = {}, options = {}) {
158
+ const config = args.config
159
+ const objects = args.objects
160
+ const hierarchy = args.hierarchy
161
+ const response = args.response
162
+ if (Array.isArray(contexts)) {
163
+ // no-op
164
+ } else if (typeof contexts === 'object') {
165
+ contexts = [contexts]
166
+ } else {
167
+ return String(contexts)
168
+ }
169
+
170
+ const contextsPrime = []
171
+ for (const icontext in contexts) {
172
+ let context = contexts[icontext]
173
+ context = Object.assign({}, context, assumed)
174
+ // let context_prime = JSON.stringify(context);
175
+ let contextPrime = context
176
+ let applied = false
177
+ const stack = args.calls.push()
178
+ for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
179
+ const generator = this.generators[igenerator]
180
+ if (generator.matches(args, objects, context, hierarchy, config, options)) {
181
+ const g = (context, options) => {
182
+ const r = this.apply(args, context, Object.assign({}, ((options||{}).assumed || {}), assumed), options)
183
+ if (Array.isArray(r)) {
184
+ return r.join(' ')
185
+ } else {
186
+ return r
187
+ }
188
+ }
189
+ const log = (message) => { this.logs.push(message) }
190
+ // this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
191
+ let errorMessage = 'The apply function did not return a value'
192
+ try {
193
+ contextPrime = generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
194
+ } catch( e ) {
195
+ // the next if handle this
196
+ contextPrime = null
197
+ if (e.stack && e.message) {
198
+ errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}`
199
+ } else if (e.error) {
200
+ errorMessage = `Error applying generator '${generator.notes}'. Error is ${e.error.join()}. Generator is ${generator.toString()}`
201
+ } else {
202
+ errorMessage = e.toString()
203
+ }
204
+ }
205
+ if (!contextPrime && contextPrime !== '') {
206
+ const widths = [10, 10, 90]
207
+ const lines = new Lines(widths)
208
+ lines.setElement(0, 0, 'Generator')
209
+ const source = `${generator.km}/#${generator.index}`
210
+ lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
211
+ lines.newRow()
212
+ lines.setElement(0, 2, generator.toString())
213
+ lines.newRow()
214
+ lines.setElement(0, 1, 'TO')
215
+ lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(sortJson(context, { depth: 25 })))})`)
216
+ lines.setElement(1, 2, JSON.stringify(sortJson(context, { depth: 25 }), null, 2))
217
+ lines.newRow()
218
+ lines.setElement(0, 1, 'STACK')
219
+ lines.setElement(0, 2, stack)
220
+ lines.newRow()
221
+ lines.setElement(0, 1, 'DEBUG')
222
+ lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
223
+ lines.newRow()
224
+ lines.setElement(0, 1, 'ERROR')
225
+ lines.setElement(0, 2, errorMessage)
226
+ this.logs.push(lines.toString())
227
+ const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
228
+ // this.logs.push(message)
229
+ // return [message]
230
+ args.calls.pop()
231
+ throw { error: [message], logs: this.logs }
232
+ }
233
+ if (((config || {}).config || {}).debug) {
234
+ const widths = [10, 10, 90]
235
+ const lines = new Lines(widths)
236
+ lines.setElement(0, 0, 'Generator')
237
+ if (generator.index > -1 && generator.km) {
238
+ // lines.setElement(0, 2, `KM '${generator.km}' ordinal: ${generator.index}`)
239
+ lines.setElement(0, 2, generator.toLabel())
240
+ }
241
+ lines.newRow()
242
+ lines.setElement(0, 1, 'APPLIED')
243
+ lines.setElement(0, 2, generator.toLabel())
244
+ lines.newRow()
245
+ lines.setElement(0, 2, generator.toString())
246
+ lines.newRow()
247
+ lines.setElement(0, 1, 'RESULT')
248
+ lines.setElement(0, 2, contextPrime)
249
+ lines.newRow()
250
+ lines.setElement(0, 1, 'STACK')
251
+ lines.setElement(0, 2, stack)
252
+ lines.newRow()
253
+ lines.newRow()
254
+ lines.setElement(0, 1, 'DEBUG')
255
+ lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
256
+ lines.setElement(0, 1, 'TO')
257
+ lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(sortJson(context, { depth: 25 })))})`)
258
+ lines.setElement(1, 2, JSON.stringify(sortJson(context, { depth: 25 }), null, 2))
259
+ this.logs.push(lines.toString())
260
+ }
261
+ applied = true
262
+ break
263
+ }
264
+ }
265
+ args.calls.pop()
266
+ if (!applied && ((config || {}).config || {}).debug) {
267
+ const widths = [10, 10, 90]
268
+ const lines = new Lines(widths)
269
+ lines.setElement(0, 0, 'Generator')
270
+ lines.setElement(0, 2, 'No generator applied')
271
+ lines.newRow()
272
+ lines.setElement(0, 1, 'TO')
273
+ lines.setElement(0, 2, JSON.stringify(context, null, 2))
274
+ this.logs.push(lines.toString())
275
+ }
276
+ contextsPrime.push(contextPrime)
277
+ }
278
+ return contextsPrime
279
+ }
280
+ }
281
+
282
+ module.exports = { Generator, Generators, normalizeGenerator }