theprogrammablemind_4wp 7.12.8 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/client.js CHANGED
@@ -81,104 +81,6 @@ const pickObjects = (config, testConfig, getObjects) => {
81
81
  return projection
82
82
  }
83
83
 
84
- // move ask to the KM's since verbatim is called probably in dialogues?
85
- const getAsk = (config) => (uuid) => {
86
- // if (!uuid) {
87
- // debugger
88
- //}
89
- return (asks) => {
90
- const ask = (ask) => {
91
- let oneShot = true // default
92
- if (ask.oneShot === false) {
93
- oneShot = false
94
- }
95
-
96
- const id_q = stableId('semantic')
97
- const id_rs = []
98
- let wasAsked = false
99
- let wasApplied = false
100
- const getWasAsked = () => {
101
- return wasAsked
102
- }
103
- const setWasAsked = (value) => {
104
- wasAsked = value
105
- }
106
- const getWasApplied = () => {
107
- return wasApplied
108
- }
109
- const setWasApplied = (value) => {
110
- wasApplied = value
111
- }
112
-
113
- const semanticsr = ask.semanticsr || []
114
- if (semanticsr.length == 0) {
115
- semanticsr.push({ match: ask.matchr, apply: ask.applyr })
116
- }
117
- for (const semantic of semanticsr) {
118
- const id_r = stableId('semantic')
119
- id_rs.push(id_r)
120
- config.addSemantic({
121
- uuid,
122
- id: id_r,
123
- tied_ids: [id_q],
124
- oneShot,
125
- where: semantic.where || ask.where || where(2),
126
- source: 'response',
127
- match: (args) => semantic.match(args),
128
- apply: (args) => {
129
- setWasApplied(true)
130
- semantic.apply(args)
131
- },
132
- })
133
- }
134
-
135
- config.addSemantic({
136
- uuid,
137
- oneShot,
138
- id: id_q,
139
- tied_ids: id_rs,
140
- where: ask.where,
141
- isQuestion: true, // do one question at a time
142
- getWasAsked,
143
- getWasApplied,
144
- onNevermind: ask.onNevermind,
145
- source: 'question',
146
- match: ({ context }) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
147
- apply: (args) => {
148
- let matchq = ask.matchq
149
- let applyq = ask.applyq
150
- if (!matchq) {
151
- let wasAsked = false
152
- matchq = () => !wasAsked,
153
- applyq = (args) => {
154
- wasAsked = true
155
- return ask.applyq(args)
156
- }
157
- }
158
- if (matchq(args)) {
159
- setWasAsked(true)
160
- setWasApplied(false)
161
- // args.context.motivationKeep = true
162
- args.verbatim(applyq(args))
163
- /*
164
- args.context.verbatim = applyq(args)
165
- args.context.isResponse = true;
166
- delete args.context.controlRemove;
167
- */
168
- args.context.controlKeepMotivation = true
169
- }
170
- args.context.cascade = true
171
- }
172
- })
173
- }
174
- if (!Array.isArray(asks)) {
175
- asks = [asks]
176
- }
177
-
178
- [...asks].reverse().forEach( (a) => ask(a) )
179
- }
180
- }
181
-
182
84
  const sameJSON = (json1, json2) => {
183
85
  const sjson1 = sortJson(json1, { depth: 25 })
184
86
  const sjson2 = sortJson(json2, { depth: 25 })
@@ -300,7 +202,6 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
300
202
  }
301
203
  // for semantics
302
204
  args.addAssumedScoped(args, {})
303
- config.getAddedArgs(args)
304
205
 
305
206
  const getAPI = (uuid) => {
306
207
  if (config && config.getAPI) {
@@ -312,14 +213,14 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
312
213
  return config.getAPIs(uuid)
313
214
  }
314
215
  }
315
- const scopedAsk = getAsk(config)
316
216
  args.getUUIDScoped = (uuid) => {
317
217
  return {
318
- ask: scopedAsk(uuid),
319
218
  api: getAPI(uuid),
320
219
  apis: getAPIs(uuid)
321
220
  }
322
221
  }
222
+ config.getAddedArgs(args)
223
+
323
224
  Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
324
225
  /*
325
226
  if (uuidForScoping) {
@@ -745,17 +646,15 @@ const loadInstance = (config, instance) => {
745
646
  const results = instance.resultss[i]
746
647
  if (results.extraConfig) {
747
648
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
748
- // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
749
649
  const uuid = config.nameToUUID(instance.name)
750
650
  // used to do a CLONE
751
- // config.addInternal(_.cloneDeep(instance.template.queries[i]), { uuid, addFirst: true, handleCalculatedProps: true })
752
- config.addInternal(instance.template.queries[i], { uuid, addFirst: true, handleCalculatedProps: true })
651
+ config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
753
652
  } else if (results.apply) {
754
653
  const objects = config.get('objects')
755
654
  const args = { objects, getObjects: getObjects(objects) }
756
- if (instance.queries) {
655
+ if (instance.configs) {
757
656
  args.isInstance = `instance${i}`
758
- args.instance = instance.queries[i]
657
+ args.instance = instance.configs[i]
759
658
  }
760
659
 
761
660
  const uuid = config.nameToUUID(instance.name)
@@ -923,15 +822,27 @@ const getConfigForTest = (config, testConfig) => {
923
822
  // configForTest[key] = config.config[key]
924
823
  if (key === 'words') {
925
824
  const words = config.config.words
926
- configForTest.words = {}
927
- for (const key of Object.keys(words)) {
825
+ configForTest.words = {
826
+ literals: {},
827
+ patterns: [],
828
+ hierarchy: [],
829
+ }
830
+
831
+ const literals = config.config.words.literals
832
+ for (const key in literals) {
928
833
  const defs = []
929
- for (const def of words[key]) {
834
+ for (const def of literals[key]) {
930
835
  // TODO handle thie uuids the right way
931
836
  defs.push(Object.assign({}, def, { uuid: undefined }))
932
837
  }
933
- configForTest.words[key] = defs
838
+ configForTest.words.literals[key] = defs
934
839
  }
840
+
841
+ const patterns = config.config.words.patterns
842
+ configForTest.words.patterns = patterns.map((pattern) => Object.assign({}, pattern, { uuid: undefined }))
843
+
844
+ const hierarchy = config.config.words.hierarchy
845
+ configForTest.words.hierarchy = hierarchy.map((hierarchy) => Object.assign({}, hierarchy, { uuid: undefined }))
935
846
  } else if (key === 'operators') {
936
847
  configForTest.operators = config.config.operators.map((operator) => Object.assign({}, operator, { uuid: undefined }))
937
848
  } else if (key === 'bridges') {
@@ -1281,7 +1192,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
1281
1192
  console.log('Errors')
1282
1193
  responses.errors.forEach((error) => console.log(` ${error}`))
1283
1194
  }
1284
- console.log("KM's loaded", config.configs.map((c) => c.name))
1195
+ console.log("KM's loaded (ordered)", config.configs.map((c) => c.name))
1285
1196
  console.log('This is the global objects from running semantics:\n', config.objects)
1286
1197
  if (!_.isEmpty(responses.learned_contextual_priorities)) {
1287
1198
  console.log('\nThe learned contextual priorties are :\n')
@@ -1404,12 +1315,12 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1404
1315
  associations: [],
1405
1316
  learned_contextual_priorities: []
1406
1317
  }
1407
- const looper = async (queries) => {
1408
- if (queries.length === 0) {
1318
+ const looper = async (configs) => {
1319
+ if (configs.length === 0) {
1409
1320
  finish()
1410
1321
  return
1411
1322
  }
1412
- const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = queries.shift()
1323
+ const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = configs.shift()
1413
1324
  // queries are strings or { query: "blah", development: true/false }
1414
1325
  if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
1415
1326
  let query = queryOrExtraConfig
@@ -1461,7 +1372,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1461
1372
  accumulators[property].push(results)
1462
1373
  accumulators.associations = accumulators.associations.concat(results.associations)
1463
1374
  accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
1464
- await looper(queries)
1375
+ await looper(configs)
1465
1376
  } catch (e) {
1466
1377
  const error = { errors: [e], query: query.query }
1467
1378
  config.config.skipSemantics = null
@@ -1475,7 +1386,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1475
1386
  setupArgs(args, config, config.logs, hierarchy)
1476
1387
  initFunction(args)
1477
1388
  accumulators[property].push({ apply: queryOrExtraConfig })
1478
- await looper(queries)
1389
+ await looper(configs)
1479
1390
  } else {
1480
1391
  // extra config is def from a time like operators or bridges or words etc
1481
1392
  // it will just get added to the config
@@ -1491,7 +1402,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1491
1402
  throw new Error(`Error processing extra config${where}: ${e.stack}}`)
1492
1403
  }
1493
1404
  accumulators[property].push({ extraConfig: true, ...extraConfig })
1494
- await looper(queries)
1405
+ await looper(configs)
1495
1406
  }
1496
1407
  }
1497
1408
  }
@@ -1531,7 +1442,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1531
1442
  return template
1532
1443
  }
1533
1444
  stabilizeOutput(accumulators)
1534
- runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries.map(updateQueries) }, accumulators), 0, 2))
1445
+ runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ configs: template.configs.map(updateQueries) }, accumulators), 0, 2))
1535
1446
 
1536
1447
  // km tests file
1537
1448
  const testsName = `./${target}.test.json`
@@ -1550,7 +1461,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1550
1461
  }
1551
1462
  let todo = []
1552
1463
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1553
- todo = todo.concat((template.queries || []).map((query, index) => {
1464
+ todo = todo.concat((template.configs || []).map((query, index) => {
1554
1465
  let pr
1555
1466
  if (index < startOfChanges) {
1556
1467
  pr = previousResultss[index]
@@ -1600,19 +1511,6 @@ const knowledgeModuleImpl = async ({
1600
1511
  acceptsAdditionalConfig = false,
1601
1512
  ...rest
1602
1513
  } = {}) => {
1603
- /*
1604
- if (description == 'fastfood related concepts') {
1605
- debugger
1606
- global.old = template.template.queries[91].bridges[0]
1607
- }
1608
- let old
1609
- if (template && template.template && template.template.queries) {
1610
- old = template.template.queries
1611
- template.template.queries = _.cloneDeep(template.template.queries)
1612
- template.wasCopied = true
1613
- }
1614
- */
1615
-
1616
1514
  const unknownArgs = Object.keys(rest)
1617
1515
  if (unknownArgs.length > 0) {
1618
1516
  throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
@@ -2270,6 +2168,7 @@ const knowledgeModule = async (...args) => {
2270
2168
 
2271
2169
  module.exports = {
2272
2170
  process: _process,
2171
+ stableId,
2273
2172
  where,
2274
2173
  w,
2275
2174
  // submitBug,
package/index.js CHANGED
@@ -15,6 +15,7 @@ module.exports = {
15
15
  knowledgeModule: client.knowledgeModule,
16
16
  ensureTestFile: client.ensureTestFile,
17
17
  where: client.where,
18
+ stableId: client.stableId,
18
19
  w: client.w,
19
20
  Config,
20
21
  Semantics,
package/package.json CHANGED
@@ -65,6 +65,6 @@
65
65
  "json-stable-stringify": "^1.0.1",
66
66
  "node-fetch": "^2.6.1"
67
67
  },
68
- "version": "7.12.8",
68
+ "version": "8.0.0",
69
69
  "license": "UNLICENSED"
70
70
  }
package/src/config.js CHANGED
@@ -26,6 +26,19 @@ const config_toServer = (config) => {
26
26
  // cant change things because copy breaks something
27
27
  }
28
28
 
29
+ const initWords = (words) => {
30
+ if (!words.literals) {
31
+ words.literals = {}
32
+ }
33
+ if (!words.patterns) {
34
+ words.patterns = []
35
+ }
36
+ if (!words.hierarchy) {
37
+ words.hierarchy = []
38
+ }
39
+ return words
40
+ }
41
+
29
42
  const debugPriority = (priority) => {
30
43
  if (global.entodictonDebugPriority) {
31
44
  if (helpers.subPriority(entodictonDebugPriority, priority)) {
@@ -123,6 +136,7 @@ const validConfigProps = (config) => {
123
136
 
124
137
  const setupInitializerFNArgs = (config, args) => {
125
138
  const aw = (word, def) => config.addWord(word, def, args.uuid)
139
+ const ap = (pattern, def) => config.addPattern(pattern, def, args.uuid)
126
140
  const ag = (generator) => config.addGenerator(generator, args.uuid, config.name)
127
141
  const km = (name) => config.getConfig(name)
128
142
  const apis = (name) => config.getConfig(name).api
@@ -130,6 +144,7 @@ const setupInitializerFNArgs = (config, args) => {
130
144
  return {
131
145
  ...args,
132
146
  addWord: aw,
147
+ addPattern: ap,
133
148
  addGenerator: ag,
134
149
  config: config.getPseudoConfig(args.uuid, args.currentConfig),
135
150
  km,
@@ -213,6 +228,9 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
213
228
  config.addHierarchy(child, bridge.id)
214
229
  }
215
230
  }
231
+ if (bridge.operator) {
232
+ config.addOperator(bridge.operator, uuid || config.uuid)
233
+ }
216
234
  if (bridge.parents) {
217
235
  for (const parent of bridge.parents) {
218
236
  config.addHierarchy(bridge.id, parent)
@@ -329,7 +347,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
329
347
  if (bridge.semantic) {
330
348
  const semantic = {
331
349
  where: bridge.semantic.where || bridge.where || client.where(3),
332
- match: ({ context }) => bridge.id == context.marker,
350
+ match: ({ context }) => bridge.id == context.marker && !context.evaluate,
333
351
  apply: (args) => bridge.semantic(args),
334
352
  applyWrapped: bridge.semantic,
335
353
  property: 'semantic'
@@ -348,7 +366,7 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
348
366
  if (moreConfig.bridges) {
349
367
  moreConfig.bridges = moreConfig.bridges.map((bridge) => {
350
368
  bridge = { ...bridge }
351
- const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
369
+ const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'operator', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
352
370
  'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
353
371
  helpers.validProps(valid, bridge, 'bridge')
354
372
  handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
@@ -409,10 +427,13 @@ const hierarchyCanonical = (element) => {
409
427
  }
410
428
  }
411
429
 
412
- const isValidDef = (word, def, config) => {
430
+ const isValidWordDef = (word, def, config) => {
431
+ // TODO trie
432
+ /*
413
433
  if (!def.id) {
414
434
  throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
415
435
  }
436
+ */
416
437
  /*
417
438
  if (!def.initial) {
418
439
  throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "initial" property: ${JSON.stringify(def)}`
@@ -429,16 +450,20 @@ const hierarchyToCanonical = (edge) => {
429
450
 
430
451
  const addWord = (config, uuid) => ({ word, id, initial }) => {
431
452
  if (!config.words) {
432
- config.words = {}
453
+ config.words = {
454
+ literals: {},
455
+ patterns: [],
456
+ hierarchy: [],
457
+ }
433
458
  }
434
- const words = config.words
459
+ const literals = config.words.literals
435
460
  const def = { id, initial, uuid }
436
- if (words[word]) {
437
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
438
- words[word].unshift(def)
461
+ if (literals[word]) {
462
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
463
+ literals[word].unshift(def)
439
464
  }
440
465
  } else {
441
- words[word] = [def]
466
+ literals[word] = [def]
442
467
  }
443
468
  }
444
469
 
@@ -453,6 +478,7 @@ const normalizeConfig = (config) => {
453
478
  }
454
479
  }
455
480
  }
481
+
456
482
  if (config.bridges) {
457
483
  for (const bridge of config.bridges) {
458
484
  if (!bridge.level) {
@@ -471,6 +497,14 @@ const normalizeConfig = (config) => {
471
497
  }
472
498
  }
473
499
  }
500
+
501
+ if (config.operators) {
502
+ for (let i = 0; i < config.operators.length; ++i) {
503
+ if (typeof config.operators[i] === 'string') {
504
+ config.operators[i] = { pattern: config.operators[i] }
505
+ }
506
+ }
507
+ }
474
508
  }
475
509
  }
476
510
 
@@ -488,8 +522,17 @@ function configDup (config, options) {
488
522
  }
489
523
 
490
524
  function setWordsUUIDs (words, uuid) {
491
- for (const key in words) {
492
- words[key] = words[key].map((o) => Object.assign(o, { uuid }))
525
+ const literals = words.literals
526
+ for (const key in literals) {
527
+ literals[key] = literals[key].map((o) => Object.assign(o, { uuid }))
528
+ }
529
+ const patterns = words.patterns
530
+ for (const pattern of patterns) {
531
+ pattern.defs.map((def) => Object.assign(def, { uuid }))
532
+ }
533
+ const hierarchy = words.hierarchy
534
+ for (const pair of hierarchy) {
535
+ pair.uuid = uuid
493
536
  }
494
537
  }
495
538
 
@@ -740,7 +783,7 @@ class Config {
740
783
  }
741
784
  const templateQueries = []
742
785
  if (this.instances && this.instances.length > 0) {
743
- for (const query of this.instances.slice(-1)[0].queries) {
786
+ for (const query of this.instances.slice(-1)[0].configs) {
744
787
  if (typeof query === 'string') {
745
788
  templateQueries.push(query)
746
789
  }
@@ -764,6 +807,7 @@ class Config {
764
807
  addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
765
808
  removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
766
809
  addWord: (...args) => this.addWord(...args, uuid),
810
+ addPattern: (...args) => this.addPattern(...args, uuid),
767
811
 
768
812
  getHierarchy: (...args) => this.config.hierarchy,
769
813
  getBridges: (...args) => this.config.bridges,
@@ -785,28 +829,6 @@ class Config {
785
829
  }
786
830
  }
787
831
 
788
- // return the config with just the elements from the included KM's
789
- baseConfig () {
790
- const operators = this.config.operators.filter((operator) => {
791
- return operator.uuid !== this.uuid
792
- })
793
- const bridges = this.config.bridges.filter((bridge) => {
794
- return bridge.uuid !== this.uuid
795
- })
796
- const words = {}
797
- for (const word in this.config.words) {
798
- const defs = this.config.words[word].filter((def) => def.uuid !== this.uuid)
799
- if (defs.length > 0) {
800
- words[word] = defs
801
- }
802
- }
803
- return {
804
- operators,
805
- bridges,
806
- words
807
- }
808
- }
809
-
810
832
  getCounter (maybeName = '') {
811
833
  const counter = this.configCounter
812
834
  this.configCounter += 1
@@ -843,7 +865,11 @@ class Config {
843
865
  namespaced: {}
844
866
  },
845
867
  description: '',
846
- words: {}, // Done
868
+ words: {
869
+ literals: {},
870
+ patterns: [],
871
+ hierarchy: [],
872
+ }, // Done
847
873
  floaters: [],
848
874
  implicits: [],
849
875
  flatten: [],
@@ -1102,8 +1128,8 @@ class Config {
1102
1128
  return elements.map(toCanonicalQuery)
1103
1129
  }
1104
1130
 
1105
- const templateQueries = toCanonicalQueries(template.queries || []).map(helpers.updateQueries)
1106
- const instanceQueries = toCanonicalQueries(instance.queries || [])
1131
+ const templateQueries = toCanonicalQueries(template.configs || []).map(helpers.updateQueries)
1132
+ const instanceQueries = toCanonicalQueries(instance.configs || [])
1107
1133
  let sameQueries = true
1108
1134
  let startOfChanges
1109
1135
  for (let iq = 0; iq < templateQueries.length; ++iq) {
@@ -1124,7 +1150,6 @@ class Config {
1124
1150
  if (templateQueries.length < instanceQueries.length) {
1125
1151
  startOfChanges = instanceQueries.length
1126
1152
  }
1127
- // const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
1128
1153
 
1129
1154
  if (debug) {
1130
1155
  if (!(instance && sameQueries && sameFragments)) {
@@ -1133,8 +1158,6 @@ class Config {
1133
1158
  console.log('sameFragments', sameFragments)
1134
1159
  // console.log("templateFragments", templateFragments)
1135
1160
  // console.log("instanceFragments", instanceFragments)
1136
- // console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
1137
- // console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
1138
1161
  }
1139
1162
  }
1140
1163
  if (startOfChanges || instance.resultss) {
@@ -1145,13 +1168,13 @@ class Config {
1145
1168
  }
1146
1169
 
1147
1170
  validifyTemplate (template) {
1148
- if (!template.queries && !template.fragments) {
1149
- throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: queries and fragments`)
1171
+ if (!template.configs && !template.fragments) {
1172
+ throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: configs and fragments`)
1150
1173
  }
1151
- for (const query of template.queries || []) {
1174
+ for (const query of template.configs || []) {
1152
1175
  if (typeof query === 'string') {
1153
1176
  } else if (query instanceof Config) {
1154
- throw new Error(`For the template for ${this.name}, each element in queries should be either a string or a structure with a config (not a Config object).`)
1177
+ throw new Error(`For the template for ${this.name}, each element in configs should be either a string or a structure with a config (not a Config object).`)
1155
1178
  }
1156
1179
  }
1157
1180
  }
@@ -1168,7 +1191,7 @@ class Config {
1168
1191
  this.logs.push(`loading template for ${this.name}`)
1169
1192
  if (options.rebuild) {
1170
1193
  // TODO fix beforeQuery
1171
- template = { fragments: [], queries: [], ...template }
1194
+ template = { fragments: [], configs: [], ...template }
1172
1195
  template.fragments = template.fragments.concat(this.dynamicFragments)
1173
1196
  client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1174
1197
  } else {
@@ -1176,7 +1199,7 @@ class Config {
1176
1199
  // this.initInstances.push({ ...instance, name: config.name })
1177
1200
  const isEmpty = (instance) => {
1178
1201
  const properties = [
1179
- 'queries',
1202
+ 'configs',
1180
1203
  'resultss',
1181
1204
  'fragments',
1182
1205
  'semantics',
@@ -1189,7 +1212,7 @@ class Config {
1189
1212
  for (let i = 0; i < instance.resultss.length; ++i) {
1190
1213
  const result = instance.resultss[i]
1191
1214
  if (result.apply) {
1192
- result.apply = template.queries[i]
1215
+ result.apply = template.configs[i]
1193
1216
  }
1194
1217
  }
1195
1218
  instance.name = this.name
@@ -1429,21 +1452,41 @@ class Config {
1429
1452
 
1430
1453
  addWordInternal (word, def, uuid) {
1431
1454
  if (!this.config.words) {
1432
- this.config.words = {}
1455
+ this.config.words = {
1456
+ literals: {},
1457
+ patterns: [],
1458
+ hierarchy: [],
1459
+ }
1433
1460
  }
1434
- const words = this.config.words
1461
+
1462
+ const literals = this.config.words.literals
1435
1463
  def = Object.assign({}, def, { uuid: uuid || this._uuid })
1436
- if (words[word]) {
1437
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
1438
- words[word].unshift(def)
1464
+ if (literals[word]) {
1465
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
1466
+ literals[word].unshift(def)
1439
1467
  }
1440
1468
  } else {
1441
- words[word] = [def]
1469
+ literals[word] = [def]
1442
1470
  }
1443
1471
 
1444
1472
  this._delta.json.words.push({ action: 'add', word, def })
1445
1473
  }
1446
1474
 
1475
+ addPattern (pattern, def, uuid) {
1476
+ if (!this.config.words) {
1477
+ this.config.words = {
1478
+ literals: {},
1479
+ patterns: [],
1480
+ hierarchy: [],
1481
+ }
1482
+ }
1483
+
1484
+ const patterns = this.config.words.patterns
1485
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
1486
+ patterns.unshift({ pattern, defs: [def] })
1487
+ this._delta.json.words.push({ action: 'add', pattern, defs: [def] })
1488
+ }
1489
+
1447
1490
  getAPI (uuid) {
1448
1491
  if (this._uuid === uuid) {
1449
1492
  return this.api
@@ -1637,13 +1680,35 @@ class Config {
1637
1680
  config.generators = config.generators.filter((element) => !element.development)
1638
1681
  config.semantics = config.semantics.filter((element) => !element.development)
1639
1682
  config.hierarchy = (config.hierarchy).filter((element) => !element.development)
1640
- for (const word in config.words) {
1641
- const defs = config.words[word] || []
1642
- config.words[word] = defs.filter((def) => !def.development)
1643
- if (config.words[word].length == 0) {
1644
- delete config.words[word]
1683
+
1684
+ const literals = config.words.literals
1685
+ for (const word in literals) {
1686
+ const defs = literals[word] || []
1687
+ literals[word] = defs.filter((def) => !def.development)
1688
+ if (literals[word].length == 0) {
1689
+ delete literals[word]
1690
+ }
1691
+ }
1692
+
1693
+ const patterns = config.words.patterns || []
1694
+ const patternsPrime = []
1695
+ for (const pattern of patterns) {
1696
+ let defs = pattern.defs || []
1697
+ defs = defs.filter((def) => !def.development)
1698
+ if (defs.length !== 0) {
1699
+ patternsPrime.push({...pattern, defs})
1645
1700
  }
1646
1701
  }
1702
+ config.words.patterns = patternsPrime
1703
+
1704
+ const hierarchy = config.words.hierarchy || []
1705
+ const hierarchyPrime = []
1706
+ for (const pair of hierarchy) {
1707
+ if (!pair.development) {
1708
+ hierarchyPrime.push(pair)
1709
+ }
1710
+ }
1711
+ config.words.hierarchy = hierarchyPrime
1647
1712
  }
1648
1713
 
1649
1714
  // configs = [ { config, namespace } ... ]
@@ -1657,7 +1722,7 @@ class Config {
1657
1722
 
1658
1723
  config.operators = config.operators || []
1659
1724
  config.bridges = config.bridges || []
1660
- config.words = config.words || {}
1725
+ config.words = config.words || { literals: {}, patterns: [], hierarchy: [] }
1661
1726
  config.generators = config.generators || []
1662
1727
  config.semantics = config.semantics || []
1663
1728
  config.hierarchy = config.hierarchy || []
@@ -1687,7 +1752,7 @@ class Config {
1687
1752
  this.instances = []
1688
1753
  this.logs = []
1689
1754
  this.dynamicFragments = []
1690
- // when running queries any bridges added are marked as transitory so that the associated will ignore those op's
1755
+ // when running configs any bridges added are marked as transitory so that the associated will ignore those op's
1691
1756
  this.transitoryMode = false
1692
1757
 
1693
1758
  // check for duplicate bridges
@@ -1709,11 +1774,8 @@ class Config {
1709
1774
  }
1710
1775
 
1711
1776
  if (config && config.words) {
1712
- for (const word of Object.keys(config.words)) {
1713
- for (const def of config.words[word]) {
1714
- isValidDef(word, def, config)
1715
- }
1716
- }
1777
+ initWords(config.words)
1778
+ isValidWordDef(config.words)
1717
1779
  }
1718
1780
 
1719
1781
  if (config && config.priorities) {
@@ -1778,7 +1840,16 @@ class Config {
1778
1840
  getAddedArgs (args) {
1779
1841
  for (let addedArgs of this.addedArgss) {
1780
1842
  addedArgs = addedArgs(args)
1843
+ const getUUIDScoped = addedArgs.getUUIDScoped
1844
+ delete addedArgs.getUUIDScoped
1781
1845
  Object.assign(args, addedArgs)
1846
+ if (getUUIDScoped) {
1847
+ const currentGetUUIDScoped = args.getUUIDScoped
1848
+ if (!currentGetUUIDScoped) {
1849
+ debugger
1850
+ }
1851
+ args.getUUIDScoped = (uuid) => Object.assign(currentGetUUIDScoped(uuid), getUUIDScoped(uuid))
1852
+ }
1782
1853
  }
1783
1854
  }
1784
1855
 
@@ -2020,10 +2091,28 @@ class Config {
2020
2091
  this.config.namespaces = ns
2021
2092
  }
2022
2093
 
2023
- if (this.config.words) {
2024
- const words = this.config.words
2025
- for (const key in words) {
2026
- words[key].forEach((o) => {
2094
+ if (!this.config.words) {
2095
+ this.config.words = {}
2096
+ }
2097
+
2098
+ if (this.config.words.literals) {
2099
+ const literals = this.config.words.literals
2100
+ for (const key in literals) {
2101
+ literals[key].forEach((o) => {
2102
+ if (o.uuid) {
2103
+ if (map[o.uuid]) {
2104
+ o.uuid = map[o.uuid]
2105
+ }
2106
+ } else {
2107
+ o.uuid = this._uuid
2108
+ }
2109
+ })
2110
+ }
2111
+ }
2112
+
2113
+ const mapDefList = (list) => {
2114
+ for (const element of list) {
2115
+ element.defs.forEach((o) => {
2027
2116
  if (o.uuid) {
2028
2117
  if (map[o.uuid]) {
2029
2118
  o.uuid = map[o.uuid]
@@ -2035,6 +2124,22 @@ class Config {
2035
2124
  }
2036
2125
  }
2037
2126
 
2127
+ if (this.config.words.patterns) {
2128
+ mapDefList(this.config.words.patterns)
2129
+ }
2130
+
2131
+ if (this.config.words.hierarchy) {
2132
+ for (const o of this.config.words.hierarchy) {
2133
+ if (o.uuid) {
2134
+ if (map[o.uuid]) {
2135
+ o.uuid = map[o.uuid]
2136
+ }
2137
+ } else {
2138
+ o.uuid = this._uuid
2139
+ }
2140
+ }
2141
+ }
2142
+
2038
2143
  if (this.config.bridges) {
2039
2144
  this.config.bridges.forEach((bridge) => {
2040
2145
  if (bridge.uuid) {
@@ -2207,11 +2312,14 @@ class Config {
2207
2312
  }
2208
2313
  */
2209
2314
 
2210
- for (const key in this.config.words) {
2211
- const values = this.config.words[key]
2212
- if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2213
- debugBreak()
2214
- return false
2315
+ const literals = this.config.words.literals
2316
+ if (literals) {
2317
+ for (const key in literals) {
2318
+ const values = literals[key]
2319
+ if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2320
+ debugBreak()
2321
+ return false
2322
+ }
2215
2323
  }
2216
2324
  }
2217
2325
 
@@ -2425,7 +2533,7 @@ class Config {
2425
2533
  this.config.hierarchy = []
2426
2534
  this.config.priorities = []
2427
2535
  this.config.associations = { positive: [], negative: [] }
2428
- this.config.words = {}
2536
+ this.config.words = initWords({})
2429
2537
 
2430
2538
  for (let i = 0; i < addInternals.length; ++i) {
2431
2539
  let name
@@ -2612,13 +2720,25 @@ class Config {
2612
2720
  }
2613
2721
 
2614
2722
  if (config.words) {
2615
- const words = {}
2616
- for (const word in config.words) {
2617
- words[word] = config.words[word].map((word) => {
2723
+ const literals = {}
2724
+ for (const word in config.words.literals) {
2725
+ literals[word] = config.words.literals[word].map((word) => {
2618
2726
  return Object.assign({}, word, { id: toNS(word.id), uuid })
2619
2727
  })
2620
2728
  }
2621
- config.words = words
2729
+ config.words.literals = literals
2730
+
2731
+ for (const pattern of config.words.patterns) {
2732
+ pattern.defs.forEach((def) => {
2733
+ def.id = toNS(def.id)
2734
+ def.uuid = uuid
2735
+ })
2736
+ }
2737
+
2738
+ for (const pair of config.words.hierarchy) {
2739
+ pair.child = toNS(pair.child)
2740
+ pair.parent = toNS(pair.parent)
2741
+ }
2622
2742
  }
2623
2743
 
2624
2744
  if (config.hierarchy) {
@@ -2739,6 +2859,7 @@ class Config {
2739
2859
  throw new Error(`Setting invalid property ${property}`)
2740
2860
  }
2741
2861
 
2862
+ // TODO trie
2742
2863
  if (property == 'words') {
2743
2864
  for (const word in value) {
2744
2865
  for (const def of value[word]) {
@@ -2803,7 +2924,8 @@ class Config {
2803
2924
  more = more.copy()
2804
2925
  more.server(this._server, this._key, this._queryParams)
2805
2926
 
2806
- this.loadOrder.addList(more.configs.map((km) => km.name || km.uuid))
2927
+ const moreConfigs = more.configs.map((km) => km.name || km.uuid)
2928
+ this.loadOrder.addList(moreConfigs)
2807
2929
 
2808
2930
  // get the new ones
2809
2931
  // remove the dups
@@ -2885,16 +3007,36 @@ class Config {
2885
3007
  continue
2886
3008
  }
2887
3009
  if (key === 'words') {
2888
- const configWords = this.config.words
2889
- const moreWords = more.words
2890
- for (const word of Object.keys(moreWords)) {
2891
- if (!configWords[word]) {
2892
- configWords[word] = []
3010
+ if (more.words.literals) {
3011
+ const literals = this.config.words.literals
3012
+ const moreLiterals = more.words.literals
3013
+ for (const word of Object.keys(moreLiterals)) {
3014
+ if (!literals[word]) {
3015
+ literals[word] = []
3016
+ }
3017
+ if (addFirst) {
3018
+ literals[word] = moreLiterals[word].concat(literals[word])
3019
+ } else {
3020
+ literals[word] = literals[word].concat(moreLiterals[word])
3021
+ }
2893
3022
  }
3023
+ }
3024
+ if (more.words.patterns) {
3025
+ const patterns = this.config.words.patterns
3026
+ const morePatterns = more.words.patterns
2894
3027
  if (addFirst) {
2895
- configWords[word] = moreWords[word].concat(configWords[word])
3028
+ this.config.words.patterns = morePatterns.concat(patterns)
2896
3029
  } else {
2897
- configWords[word] = configWords[word].concat(moreWords[word])
3030
+ this.config.words.patterns = patterns.concat(morePatterns)
3031
+ }
3032
+ }
3033
+ if (more.words.hierarchy) {
3034
+ const hierarchy = this.config.words.hierarchy
3035
+ const moreHierarchy = more.words.hierarchy
3036
+ if (addFirst) {
3037
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3038
+ } else {
3039
+ this.config.words.hierarchy = hierarchy.concat(moreHierarchy)
2898
3040
  }
2899
3041
  }
2900
3042
  } else if (key === 'name') {
@@ -3006,14 +3148,25 @@ class Config {
3006
3148
  continue
3007
3149
  }
3008
3150
  if (key === 'words') {
3009
- const configWords = this.config.words
3010
- const moreWords = more.words
3011
- for (const word of Object.keys(moreWords)) {
3012
- if (!configWords[word]) {
3013
- configWords[word] = []
3151
+ if (this.config.words.literals) {
3152
+ const literals = this.config.words.literals
3153
+ const moreLiterals = more.words.literals
3154
+ for (const word of Object.keys(moreLiterals)) {
3155
+ if (!literals[word]) {
3156
+ literals[word] = []
3157
+ }
3158
+ literals[word] = moreLiterals[word].concat(literals[word])
3014
3159
  }
3015
- // configWords[word] = configWords[word].concat(moreWords[word])
3016
- configWords[word] = moreWords[word].concat(configWords[word])
3160
+ }
3161
+ if (this.config.words.patterns) {
3162
+ const patterns = this.config.words.patterns
3163
+ const morePatterns = more.words.patterns
3164
+ this.config.words.patterns = morePatterns.concat(patterns)
3165
+ }
3166
+ if (this.config.words.hierarchy) {
3167
+ const hierarchy = this.config.words.hierarchy
3168
+ const moreHierarchy = more.words.hierarchy
3169
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3017
3170
  }
3018
3171
  } else if (key === 'name') {
3019
3172
  /*
package/src/digraph.js CHANGED
@@ -113,19 +113,31 @@ class Digraph {
113
113
  }
114
114
 
115
115
  minima (nodes) {
116
- let minima = new Set(nodes)
117
- const ancestors = new Set([])
118
- nodes.forEach((node) => {
119
- this.ancestors(node).forEach((n) => ancestors.add(n))
120
- })
121
- ancestors.forEach((n) => minima.delete(n))
122
- if (minima.size === 0) {
123
- // all unrelated
124
- minima = new Set(nodes)
116
+ nodes = new Set(nodes)
117
+ const nodeToDescendants = {}
118
+ for (const node of nodes) {
119
+ nodeToDescendants[node] = this.descendants(node)
120
+ }
121
+ let minima = new Set()
122
+ for (const node of nodes) {
123
+ let okay = true
124
+ for (const key of nodeToDescendants[node]) {
125
+ if (nodes.has(key)) {
126
+ if (key in nodeToDescendants && nodeToDescendants[key].has(node)) {
127
+ continue
128
+ }
129
+ okay = false
130
+ break
131
+ }
132
+ }
133
+ if (okay) {
134
+ minima.add(node)
135
+ }
125
136
  }
126
137
  return minima
127
138
  }
128
139
 
140
+ /*
129
141
  maxima (nodes) {
130
142
  const maxima = new Set(nodes)
131
143
  const descendants = new Set([])
@@ -135,14 +147,21 @@ class Digraph {
135
147
  descendants.forEach((n) => maxima.delete(n))
136
148
  return maxima
137
149
  }
150
+ */
138
151
 
139
152
  add (child, parent) {
140
153
  this._edges.push([child, parent])
141
154
  }
142
155
 
156
+ exists(child, parent) {
157
+ return this._edges.find((edge) => edge[0] == child && edge[1] == parent)
158
+ }
159
+
143
160
  addList (l) {
144
161
  for (let i = 1; i < l.length; ++i) {
145
- this._edges.push([l[i - 1], l[i]])
162
+ if (!this.exists(l[i-1], l[i])) {
163
+ this._edges.push([l[i - 1], l[i]])
164
+ }
146
165
  }
147
166
  }
148
167
 
@@ -81,19 +81,31 @@ class DigraphInternal {
81
81
  }
82
82
 
83
83
  minima (nodes) {
84
- let minima = new Set(nodes)
85
- const ancestors = new Set([])
86
- nodes.forEach((node) => {
87
- this.ancestors(node).forEach((n) => ancestors.add(n))
88
- })
89
- ancestors.forEach((n) => minima.delete(n))
90
- if (minima.size === 0) {
91
- // all unrelated
92
- minima = new Set(nodes)
84
+ nodes = new Set(nodes)
85
+ const nodeToDescendants = {}
86
+ for (const node of nodes) {
87
+ nodeToDescendants[node] = this.descendants(node)
88
+ }
89
+ let minima = new Set()
90
+ for (const node of nodes) {
91
+ let okay = true
92
+ for (const key of nodeToDescendants[node]) {
93
+ if (nodes.has(key)) {
94
+ if (key in nodeToDescendants && nodeToDescendants[key].has(node)) {
95
+ continue
96
+ }
97
+ okay = false
98
+ break
99
+ }
100
+ }
101
+ if (okay) {
102
+ minima.add(node)
103
+ }
93
104
  }
94
105
  return minima
95
106
  }
96
107
 
108
+ /*
97
109
  maxima (nodes) {
98
110
  const maxima = new Set(nodes)
99
111
  const descendants = new Set([])
@@ -103,14 +115,21 @@ class DigraphInternal {
103
115
  descendants.forEach((n) => maxima.delete(n))
104
116
  return maxima
105
117
  }
118
+ */
106
119
 
107
120
  add (child, parent) {
108
121
  this._edges.push([child, parent])
109
122
  }
110
123
 
124
+ exists(child, parent) {
125
+ return this._edges.findIndex((edge) => edge[0] == child && edge[1] == parent) != -1
126
+ }
127
+
111
128
  addList (l) {
112
129
  for (let i = 1; i < l.length; ++i) {
113
- this._edges.push([l[i - 1], l[i]])
130
+ if (!this.exists(l[i-1], l[i])) {
131
+ this._edges.push([l[i - 1], l[i]])
132
+ }
114
133
  }
115
134
  }
116
135