theprogrammablemind 7.12.8-beta.5 → 7.12.8-beta.6

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.
Files changed (3) hide show
  1. package/client.js +27 -30
  2. package/package.json +1 -1
  3. package/src/config.js +320 -89
package/client.js CHANGED
@@ -646,17 +646,15 @@ const loadInstance = (config, instance) => {
646
646
  const results = instance.resultss[i]
647
647
  if (results.extraConfig) {
648
648
  // config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
649
- // config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
650
649
  const uuid = config.nameToUUID(instance.name)
651
650
  // used to do a CLONE
652
- // config.addInternal(_.cloneDeep(instance.template.queries[i]), { uuid, addFirst: true, handleCalculatedProps: true })
653
- config.addInternal(instance.template.queries[i], { uuid, addFirst: true, handleCalculatedProps: true })
651
+ config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
654
652
  } else if (results.apply) {
655
653
  const objects = config.get('objects')
656
654
  const args = { objects, getObjects: getObjects(objects) }
657
- if (instance.queries) {
655
+ if (instance.configs) {
658
656
  args.isInstance = `instance${i}`
659
- args.instance = instance.queries[i]
657
+ args.instance = instance.configs[i]
660
658
  }
661
659
 
662
660
  const uuid = config.nameToUUID(instance.name)
@@ -824,15 +822,27 @@ const getConfigForTest = (config, testConfig) => {
824
822
  // configForTest[key] = config.config[key]
825
823
  if (key === 'words') {
826
824
  const words = config.config.words
827
- configForTest.words = {}
828
- 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) {
829
833
  const defs = []
830
- for (const def of words[key]) {
834
+ for (const def of literals[key]) {
831
835
  // TODO handle thie uuids the right way
832
836
  defs.push(Object.assign({}, def, { uuid: undefined }))
833
837
  }
834
- configForTest.words[key] = defs
838
+ configForTest.words.literals[key] = defs
835
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 }))
836
846
  } else if (key === 'operators') {
837
847
  configForTest.operators = config.config.operators.map((operator) => Object.assign({}, operator, { uuid: undefined }))
838
848
  } else if (key === 'bridges') {
@@ -1305,12 +1315,12 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1305
1315
  associations: [],
1306
1316
  learned_contextual_priorities: []
1307
1317
  }
1308
- const looper = async (queries) => {
1309
- if (queries.length === 0) {
1318
+ const looper = async (configs) => {
1319
+ if (configs.length === 0) {
1310
1320
  finish()
1311
1321
  return
1312
1322
  }
1313
- const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = queries.shift()
1323
+ const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = configs.shift()
1314
1324
  // queries are strings or { query: "blah", development: true/false }
1315
1325
  if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
1316
1326
  let query = queryOrExtraConfig
@@ -1362,7 +1372,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1362
1372
  accumulators[property].push(results)
1363
1373
  accumulators.associations = accumulators.associations.concat(results.associations)
1364
1374
  accumulators.learned_contextual_priorities = accumulators.learned_contextual_priorities.concat(results.learned_contextual_priorities)
1365
- await looper(queries)
1375
+ await looper(configs)
1366
1376
  } catch (e) {
1367
1377
  const error = { errors: [e], query: query.query }
1368
1378
  config.config.skipSemantics = null
@@ -1376,7 +1386,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1376
1386
  setupArgs(args, config, config.logs, hierarchy)
1377
1387
  initFunction(args)
1378
1388
  accumulators[property].push({ apply: queryOrExtraConfig })
1379
- await looper(queries)
1389
+ await looper(configs)
1380
1390
  } else {
1381
1391
  // extra config is def from a time like operators or bridges or words etc
1382
1392
  // it will just get added to the config
@@ -1392,7 +1402,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1392
1402
  throw new Error(`Error processing extra config${where}: ${e.stack}}`)
1393
1403
  }
1394
1404
  accumulators[property].push({ extraConfig: true, ...extraConfig })
1395
- await looper(queries)
1405
+ await looper(configs)
1396
1406
  }
1397
1407
  }
1398
1408
  }
@@ -1432,7 +1442,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1432
1442
  return template
1433
1443
  }
1434
1444
  stabilizeOutput(accumulators)
1435
- 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))
1436
1446
 
1437
1447
  // km tests file
1438
1448
  const testsName = `./${target}.test.json`
@@ -1451,7 +1461,7 @@ const rebuildTemplate = async ({ config, target, previousResultss, startOfChange
1451
1461
  }
1452
1462
  let todo = []
1453
1463
  todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
1454
- todo = todo.concat((template.queries || []).map((query, index) => {
1464
+ todo = todo.concat((template.configs || []).map((query, index) => {
1455
1465
  let pr
1456
1466
  if (index < startOfChanges) {
1457
1467
  pr = previousResultss[index]
@@ -1501,19 +1511,6 @@ const knowledgeModuleImpl = async ({
1501
1511
  acceptsAdditionalConfig = false,
1502
1512
  ...rest
1503
1513
  } = {}) => {
1504
- /*
1505
- if (description == 'fastfood related concepts') {
1506
- debugger
1507
- global.old = template.template.queries[91].bridges[0]
1508
- }
1509
- let old
1510
- if (template && template.template && template.template.queries) {
1511
- old = template.template.queries
1512
- template.template.queries = _.cloneDeep(template.template.queries)
1513
- template.wasCopied = true
1514
- }
1515
- */
1516
-
1517
1514
  const unknownArgs = Object.keys(rest)
1518
1515
  if (unknownArgs.length > 0) {
1519
1516
  throw new Error(`Unknown arguments to knowledgeModule: ${unknownArgs.join()}`)
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-beta.5",
68
+ "version": "7.12.8-beta.6",
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)) {
@@ -92,6 +105,7 @@ const validConfigProps = (config) => {
92
105
  'objects',
93
106
  'bridges',
94
107
  'operators',
108
+ 'trie',
95
109
  'words',
96
110
  'priorities',
97
111
  'associations',
@@ -123,6 +137,7 @@ const validConfigProps = (config) => {
123
137
 
124
138
  const setupInitializerFNArgs = (config, args) => {
125
139
  const aw = (word, def) => config.addWord(word, def, args.uuid)
140
+ const ap = (pattern, def) => config.addPattern(pattern, def, args.uuid)
126
141
  const ag = (generator) => config.addGenerator(generator, args.uuid, config.name)
127
142
  const km = (name) => config.getConfig(name)
128
143
  const apis = (name) => config.getConfig(name).api
@@ -130,6 +145,7 @@ const setupInitializerFNArgs = (config, args) => {
130
145
  return {
131
146
  ...args,
132
147
  addWord: aw,
148
+ addPattern: ap,
133
149
  addGenerator: ag,
134
150
  config: config.getPseudoConfig(args.uuid, args.currentConfig),
135
151
  km,
@@ -412,10 +428,13 @@ const hierarchyCanonical = (element) => {
412
428
  }
413
429
  }
414
430
 
415
- const isValidDef = (word, def, config) => {
431
+ const isValidWordDef = (word, def, config) => {
432
+ // TODO trie
433
+ /*
416
434
  if (!def.id) {
417
435
  throw new Error(`In the KM "${config.name}", for the word ${word} the following definition is missing the "id" property: ${JSON.stringify(def)}`)
418
436
  }
437
+ */
419
438
  /*
420
439
  if (!def.initial) {
421
440
  throw `In the KM "${config.name}", for the word ${word} the following definition is missing the "initial" property: ${JSON.stringify(def)}`
@@ -423,6 +442,10 @@ const isValidDef = (word, def, config) => {
423
442
  */
424
443
  }
425
444
 
445
+ const isValidTrie = (trie) => {
446
+ return true
447
+ }
448
+
426
449
  const hierarchyToCanonical = (edge) => {
427
450
  if (Array.isArray(edge)) {
428
451
  return { child: edge[0], parent: edge[1] }
@@ -430,18 +453,33 @@ const hierarchyToCanonical = (edge) => {
430
453
  return edge
431
454
  }
432
455
 
456
+ // for trie defs
457
+
458
+ const addPattern = (config, uuid) => ({ pattern, defs }) => {
459
+ if (!config.trie) {
460
+ config.trie = []
461
+ }
462
+ const trie = config.trie
463
+ const def = { id, initial, uuid }
464
+ trie.unshift({ pattern, defs })
465
+ }
466
+
433
467
  const addWord = (config, uuid) => ({ word, id, initial }) => {
434
468
  if (!config.words) {
435
- config.words = {}
469
+ config.words = {
470
+ literals: {},
471
+ patterns: [],
472
+ hierarchy: [],
473
+ }
436
474
  }
437
- const words = config.words
475
+ const literals = config.words.literals
438
476
  const def = { id, initial, uuid }
439
- if (words[word]) {
440
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
441
- words[word].unshift(def)
477
+ if (literals[word]) {
478
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
479
+ literals[word].unshift(def)
442
480
  }
443
481
  } else {
444
- words[word] = [def]
482
+ literals[word] = [def]
445
483
  }
446
484
  }
447
485
 
@@ -500,8 +538,23 @@ function configDup (config, options) {
500
538
  }
501
539
 
502
540
  function setWordsUUIDs (words, uuid) {
503
- for (const key in words) {
504
- words[key] = words[key].map((o) => Object.assign(o, { uuid }))
541
+ const literals = words.literals
542
+ for (const key in literals) {
543
+ literals[key] = literals[key].map((o) => Object.assign(o, { uuid }))
544
+ }
545
+ const patterns = words.patterns
546
+ for (const pattern of patterns) {
547
+ pattern.defs.map((def) => Object.assign(def, { uuid }))
548
+ }
549
+ const hierarchy = words.hierarchy
550
+ for (const pair of hierarchy) {
551
+ pair.uuid = uuid
552
+ }
553
+ }
554
+
555
+ function setTrieUUIDs (patterns, uuid) {
556
+ for (const pattern of patterns) {
557
+ pattern.defs.map((def) => Object.assign(def, { uuid }))
505
558
  }
506
559
  }
507
560
 
@@ -535,6 +588,9 @@ function applyUUID (config, uuid) {
535
588
  if (config.words) {
536
589
  setWordsUUIDs(config.words, uuid)
537
590
  }
591
+ if (config.trie) {
592
+ setTrieUUIDs(config.trie, uuid)
593
+ }
538
594
  for (const property of bags) {
539
595
  if (config[property]) {
540
596
  config[property].forEach((bag) => { bag.uuid = uuid })
@@ -752,7 +808,7 @@ class Config {
752
808
  }
753
809
  const templateQueries = []
754
810
  if (this.instances && this.instances.length > 0) {
755
- for (const query of this.instances.slice(-1)[0].queries) {
811
+ for (const query of this.instances.slice(-1)[0].configs) {
756
812
  if (typeof query === 'string') {
757
813
  templateQueries.push(query)
758
814
  }
@@ -776,6 +832,7 @@ class Config {
776
832
  addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
777
833
  removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
778
834
  addWord: (...args) => this.addWord(...args, uuid),
835
+ addPattern: (...args) => this.addPattern(...args, uuid),
779
836
 
780
837
  getHierarchy: (...args) => this.config.hierarchy,
781
838
  getBridges: (...args) => this.config.bridges,
@@ -797,28 +854,6 @@ class Config {
797
854
  }
798
855
  }
799
856
 
800
- // return the config with just the elements from the included KM's
801
- baseConfig () {
802
- const operators = this.config.operators.filter((operator) => {
803
- return operator.uuid !== this.uuid
804
- })
805
- const bridges = this.config.bridges.filter((bridge) => {
806
- return bridge.uuid !== this.uuid
807
- })
808
- const words = {}
809
- for (const word in this.config.words) {
810
- const defs = this.config.words[word].filter((def) => def.uuid !== this.uuid)
811
- if (defs.length > 0) {
812
- words[word] = defs
813
- }
814
- }
815
- return {
816
- operators,
817
- bridges,
818
- words
819
- }
820
- }
821
-
822
857
  getCounter (maybeName = '') {
823
858
  const counter = this.configCounter
824
859
  this.configCounter += 1
@@ -855,7 +890,12 @@ class Config {
855
890
  namespaced: {}
856
891
  },
857
892
  description: '',
858
- words: {}, // Done
893
+ trie: [],
894
+ words: {
895
+ literals: {},
896
+ patterns: [],
897
+ hierarchy: [],
898
+ }, // Done
859
899
  floaters: [],
860
900
  implicits: [],
861
901
  flatten: [],
@@ -883,6 +923,7 @@ class Config {
883
923
  'eqClasses',
884
924
  'priorities',
885
925
  'associations',
926
+ 'trie',
886
927
  'words',
887
928
  'floaters',
888
929
  'implicits',
@@ -1114,8 +1155,8 @@ class Config {
1114
1155
  return elements.map(toCanonicalQuery)
1115
1156
  }
1116
1157
 
1117
- const templateQueries = toCanonicalQueries(template.queries || []).map(helpers.updateQueries)
1118
- const instanceQueries = toCanonicalQueries(instance.queries || [])
1158
+ const templateQueries = toCanonicalQueries(template.configs || []).map(helpers.updateQueries)
1159
+ const instanceQueries = toCanonicalQueries(instance.configs || [])
1119
1160
  let sameQueries = true
1120
1161
  let startOfChanges
1121
1162
  for (let iq = 0; iq < templateQueries.length; ++iq) {
@@ -1136,7 +1177,6 @@ class Config {
1136
1177
  if (templateQueries.length < instanceQueries.length) {
1137
1178
  startOfChanges = instanceQueries.length
1138
1179
  }
1139
- // const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
1140
1180
 
1141
1181
  if (debug) {
1142
1182
  if (!(instance && sameQueries && sameFragments)) {
@@ -1145,8 +1185,6 @@ class Config {
1145
1185
  console.log('sameFragments', sameFragments)
1146
1186
  // console.log("templateFragments", templateFragments)
1147
1187
  // console.log("instanceFragments", instanceFragments)
1148
- // console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
1149
- // console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
1150
1188
  }
1151
1189
  }
1152
1190
  if (startOfChanges || instance.resultss) {
@@ -1157,13 +1195,13 @@ class Config {
1157
1195
  }
1158
1196
 
1159
1197
  validifyTemplate (template) {
1160
- if (!template.queries && !template.fragments) {
1161
- throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: queries and fragments`)
1198
+ if (!template.configs && !template.fragments) {
1199
+ throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: configs and fragments`)
1162
1200
  }
1163
- for (const query of template.queries || []) {
1201
+ for (const query of template.configs || []) {
1164
1202
  if (typeof query === 'string') {
1165
1203
  } else if (query instanceof Config) {
1166
- 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).`)
1204
+ 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).`)
1167
1205
  }
1168
1206
  }
1169
1207
  }
@@ -1180,7 +1218,7 @@ class Config {
1180
1218
  this.logs.push(`loading template for ${this.name}`)
1181
1219
  if (options.rebuild) {
1182
1220
  // TODO fix beforeQuery
1183
- template = { fragments: [], queries: [], ...template }
1221
+ template = { fragments: [], configs: [], ...template }
1184
1222
  template.fragments = template.fragments.concat(this.dynamicFragments)
1185
1223
  client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
1186
1224
  } else {
@@ -1188,7 +1226,7 @@ class Config {
1188
1226
  // this.initInstances.push({ ...instance, name: config.name })
1189
1227
  const isEmpty = (instance) => {
1190
1228
  const properties = [
1191
- 'queries',
1229
+ 'configs',
1192
1230
  'resultss',
1193
1231
  'fragments',
1194
1232
  'semantics',
@@ -1201,7 +1239,7 @@ class Config {
1201
1239
  for (let i = 0; i < instance.resultss.length; ++i) {
1202
1240
  const result = instance.resultss[i]
1203
1241
  if (result.apply) {
1204
- result.apply = template.queries[i]
1242
+ result.apply = template.configs[i]
1205
1243
  }
1206
1244
  }
1207
1245
  instance.name = this.name
@@ -1435,27 +1473,59 @@ class Config {
1435
1473
  this._delta.json.operators.push({ action: 'add', operator })
1436
1474
  }
1437
1475
 
1476
+ /*
1477
+ addPattern (pattern, def, uuid) {
1478
+ if (!this.config.trie) {
1479
+ this.config.trie = []
1480
+ }
1481
+ const patterns = this.config.trie
1482
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
1483
+ patterns.unshift({ pattern, def })
1484
+ this._delta.json.trie.push({ action: 'add', pattern, def })
1485
+ }
1486
+ */
1487
+
1438
1488
  addWord (word, def, uuid) {
1439
1489
  this.addWordInternal(word, def, uuid)
1440
1490
  }
1441
1491
 
1442
1492
  addWordInternal (word, def, uuid) {
1443
1493
  if (!this.config.words) {
1444
- this.config.words = {}
1494
+ this.config.words = {
1495
+ literals: {},
1496
+ patterns: [],
1497
+ hierarchy: [],
1498
+ }
1445
1499
  }
1446
- const words = this.config.words
1500
+
1501
+ const literals = this.config.words.literals
1447
1502
  def = Object.assign({}, def, { uuid: uuid || this._uuid })
1448
- if (words[word]) {
1449
- if (!words[word].some((e) => helpers.safeEquals(e, def))) {
1450
- words[word].unshift(def)
1503
+ if (literals[word]) {
1504
+ if (!literals[word].some((e) => helpers.safeEquals(e, def))) {
1505
+ literals[word].unshift(def)
1451
1506
  }
1452
1507
  } else {
1453
- words[word] = [def]
1508
+ literals[word] = [def]
1454
1509
  }
1455
1510
 
1456
1511
  this._delta.json.words.push({ action: 'add', word, def })
1457
1512
  }
1458
1513
 
1514
+ addPattern (pattern, def, uuid) {
1515
+ if (!this.config.words) {
1516
+ this.config.words = {
1517
+ literals: {},
1518
+ patterns: [],
1519
+ hierarchy: [],
1520
+ }
1521
+ }
1522
+
1523
+ const patterns = this.config.words.patterns
1524
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
1525
+ patterns.unshift({ pattern, defs: [def] })
1526
+ this._delta.json.words.push({ action: 'add', pattern, defs: [def] })
1527
+ }
1528
+
1459
1529
  getAPI (uuid) {
1460
1530
  if (this._uuid === uuid) {
1461
1531
  return this.api
@@ -1649,13 +1719,47 @@ class Config {
1649
1719
  config.generators = config.generators.filter((element) => !element.development)
1650
1720
  config.semantics = config.semantics.filter((element) => !element.development)
1651
1721
  config.hierarchy = (config.hierarchy).filter((element) => !element.development)
1652
- for (const word in config.words) {
1653
- const defs = config.words[word] || []
1654
- config.words[word] = defs.filter((def) => !def.development)
1655
- if (config.words[word].length == 0) {
1656
- delete config.words[word]
1722
+
1723
+ const literals = config.words.literals
1724
+ for (const word in literals) {
1725
+ const defs = literals[word] || []
1726
+ literals[word] = defs.filter((def) => !def.development)
1727
+ if (literals[word].length == 0) {
1728
+ delete literals[word]
1729
+ }
1730
+ }
1731
+
1732
+ const patterns = config.words.patterns || []
1733
+ const patternsPrime = []
1734
+ for (const pattern of patterns) {
1735
+ let defs = pattern.defs || []
1736
+ defs = defs.filter((def) => !def.development)
1737
+ if (defs.length !== 0) {
1738
+ patternsPrime.push({...pattern, defs})
1657
1739
  }
1658
1740
  }
1741
+ config.words.patterns = patternsPrime
1742
+
1743
+ const hierarchy = config.words.hierarchy || []
1744
+ const hierarchyPrime = []
1745
+ for (const pair of hierarchy) {
1746
+ if (!pair.development) {
1747
+ hierarchyPrime.push(pair)
1748
+ }
1749
+ }
1750
+ config.words.hierarchy = hierarchyPrime
1751
+
1752
+ const toDelete = []
1753
+ for (const [index, pattern] of config.trie.entries()) {
1754
+ const defs = pattern.defs
1755
+ pattern.defs = defs.filter((def) => !def.development)
1756
+ if (pattern.defs.length == 0) {
1757
+ toDelete.unshift(index)
1758
+ }
1759
+ }
1760
+ for (const index of toDelete) {
1761
+ config.patterns.split(index, 1)
1762
+ }
1659
1763
  }
1660
1764
 
1661
1765
  // configs = [ { config, namespace } ... ]
@@ -1669,7 +1773,8 @@ class Config {
1669
1773
 
1670
1774
  config.operators = config.operators || []
1671
1775
  config.bridges = config.bridges || []
1672
- config.words = config.words || {}
1776
+ config.trie = config.trie || []
1777
+ config.words = config.words || { literals: {}, patterns: [], hierarchy: [] }
1673
1778
  config.generators = config.generators || []
1674
1779
  config.semantics = config.semantics || []
1675
1780
  config.hierarchy = config.hierarchy || []
@@ -1699,7 +1804,7 @@ class Config {
1699
1804
  this.instances = []
1700
1805
  this.logs = []
1701
1806
  this.dynamicFragments = []
1702
- // when running queries any bridges added are marked as transitory so that the associated will ignore those op's
1807
+ // when running configs any bridges added are marked as transitory so that the associated will ignore those op's
1703
1808
  this.transitoryMode = false
1704
1809
 
1705
1810
  // check for duplicate bridges
@@ -1721,11 +1826,12 @@ class Config {
1721
1826
  }
1722
1827
 
1723
1828
  if (config && config.words) {
1724
- for (const word of Object.keys(config.words)) {
1725
- for (const def of config.words[word]) {
1726
- isValidDef(word, def, config)
1727
- }
1728
- }
1829
+ initWords(config.words)
1830
+ isValidWordDef(config.words)
1831
+ }
1832
+
1833
+ if (config && config.trie) {
1834
+ isValidTrie(config.trie)
1729
1835
  }
1730
1836
 
1731
1837
  if (config && config.priorities) {
@@ -1830,6 +1936,7 @@ class Config {
1830
1936
  this._delta = {
1831
1937
  cacheKey,
1832
1938
  json: {
1939
+ trie: [],
1833
1940
  words: [],
1834
1941
  operators: [],
1835
1942
  bridges: [],
@@ -2014,6 +2121,7 @@ class Config {
2014
2121
  setUUIDs () {
2015
2122
  this.config.bridges && this.config.bridges.forEach((bridge) => { bridge.uuid = this._uuid })
2016
2123
  this.config.words && setWordsUUIDs(this.config.words, this._uuid)
2124
+ this.config.trie && setTrieUUIDs(this.config.trie, this._uuid)
2017
2125
  this.config.operators && this.config.operators.forEach((operator) => { operator.uuid = this._uuid })
2018
2126
  const ids = Array.from(new Set(this.config.bridges.map((bridge) => bridge.id)))
2019
2127
  ids.sort()
@@ -2041,10 +2149,28 @@ class Config {
2041
2149
  this.config.namespaces = ns
2042
2150
  }
2043
2151
 
2044
- if (this.config.words) {
2045
- const words = this.config.words
2046
- for (const key in words) {
2047
- words[key].forEach((o) => {
2152
+ if (!this.config.words) {
2153
+ this.config.words = {}
2154
+ }
2155
+
2156
+ if (this.config.words.literals) {
2157
+ const literals = this.config.words.literals
2158
+ for (const key in literals) {
2159
+ literals[key].forEach((o) => {
2160
+ if (o.uuid) {
2161
+ if (map[o.uuid]) {
2162
+ o.uuid = map[o.uuid]
2163
+ }
2164
+ } else {
2165
+ o.uuid = this._uuid
2166
+ }
2167
+ })
2168
+ }
2169
+ }
2170
+
2171
+ const mapDefList = (list) => {
2172
+ for (const element of list) {
2173
+ element.defs.forEach((o) => {
2048
2174
  if (o.uuid) {
2049
2175
  if (map[o.uuid]) {
2050
2176
  o.uuid = map[o.uuid]
@@ -2056,6 +2182,26 @@ class Config {
2056
2182
  }
2057
2183
  }
2058
2184
 
2185
+ if (this.config.words.patterns) {
2186
+ mapDefList(this.config.words.patterns)
2187
+ }
2188
+
2189
+ if (this.config.words.hierarchy) {
2190
+ for (const o of this.config.words.hierarchy) {
2191
+ if (o.uuid) {
2192
+ if (map[o.uuid]) {
2193
+ o.uuid = map[o.uuid]
2194
+ }
2195
+ } else {
2196
+ o.uuid = this._uuid
2197
+ }
2198
+ }
2199
+ }
2200
+
2201
+ if (this.config.trie) {
2202
+ mapDefList(this.config.trie)
2203
+ }
2204
+
2059
2205
  if (this.config.bridges) {
2060
2206
  this.config.bridges.forEach((bridge) => {
2061
2207
  if (bridge.uuid) {
@@ -2228,14 +2374,20 @@ class Config {
2228
2374
  }
2229
2375
  */
2230
2376
 
2231
- for (const key in this.config.words) {
2232
- const values = this.config.words[key]
2233
- if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2234
- debugBreak()
2235
- return false
2377
+ const literals = this.config.words.literals
2378
+ if (literals) {
2379
+ for (const key in literals) {
2380
+ const values = literals[key]
2381
+ if (values.some((word) => (Object.keys(word).includes('uuid') && !word.uuid))) {
2382
+ debugBreak()
2383
+ return false
2384
+ }
2236
2385
  }
2237
2386
  }
2238
2387
 
2388
+ // TODO trie
2389
+ isValidTrie(this.config.trie)
2390
+
2239
2391
  const kmsUuids = this.configs.map((km) => km.uuid)
2240
2392
  const bridgesUuids = this.config.bridges.map((bridge) => bridge.uuid).filter((uuid) => uuid)
2241
2393
  let result = true
@@ -2438,6 +2590,7 @@ class Config {
2438
2590
  hierarchy: this.config.hierarchy,
2439
2591
  priorities: this.config.priorities,
2440
2592
  associations: this.config.associations,
2593
+ trie: this.config.trie,
2441
2594
  words: this.config.words
2442
2595
  }
2443
2596
 
@@ -2446,7 +2599,9 @@ class Config {
2446
2599
  this.config.hierarchy = []
2447
2600
  this.config.priorities = []
2448
2601
  this.config.associations = { positive: [], negative: [] }
2449
- this.config.words = {}
2602
+ this.config.words = initWords({})
2603
+
2604
+ this.config.trie = []
2450
2605
 
2451
2606
  for (let i = 0; i < addInternals.length; ++i) {
2452
2607
  let name
@@ -2633,6 +2788,30 @@ class Config {
2633
2788
  }
2634
2789
 
2635
2790
  if (config.words) {
2791
+ const literals = {}
2792
+ for (const word in config.words.literals) {
2793
+ literals[word] = config.words.literals[word].map((word) => {
2794
+ return Object.assign({}, word, { id: toNS(word.id), uuid })
2795
+ })
2796
+ }
2797
+ config.words.literals = literals
2798
+
2799
+ for (const pattern of config.words.patterns) {
2800
+ pattern.defs.forEach((def) => {
2801
+ def.id = toNS(def.id)
2802
+ def.uuid = uuid
2803
+ })
2804
+ }
2805
+
2806
+ for (const pair of config.words.hierarchy) {
2807
+ pair.child = toNS(pair.child)
2808
+ pair.parent = toNS(pair.parent)
2809
+ }
2810
+ }
2811
+
2812
+ if (config.trie) {
2813
+ // TODO not currently used
2814
+ /*
2636
2815
  const words = {}
2637
2816
  for (const word in config.words) {
2638
2817
  words[word] = config.words[word].map((word) => {
@@ -2640,6 +2819,7 @@ class Config {
2640
2819
  })
2641
2820
  }
2642
2821
  config.words = words
2822
+ */
2643
2823
  }
2644
2824
 
2645
2825
  if (config.hierarchy) {
@@ -2760,7 +2940,9 @@ class Config {
2760
2940
  throw new Error(`Setting invalid property ${property}`)
2761
2941
  }
2762
2942
 
2943
+ // TODO trie
2763
2944
  if (property == 'words') {
2945
+ throw "you need to fix this"
2764
2946
  for (const word in value) {
2765
2947
  for (const def of value[word]) {
2766
2948
  if (!def.uuid) {
@@ -2770,6 +2952,10 @@ class Config {
2770
2952
  }
2771
2953
  }
2772
2954
 
2955
+ if (property == 'trie') {
2956
+ isValidTrie(value)
2957
+ }
2958
+
2773
2959
  if (['operators', 'bridges'].includes(property)) {
2774
2960
  for (const def of value) {
2775
2961
  if (!def.uuid) {
@@ -2906,17 +3092,47 @@ class Config {
2906
3092
  this.config[key] = value
2907
3093
  continue
2908
3094
  }
2909
- if (key === 'words') {
2910
- const configWords = this.config.words
2911
- const moreWords = more.words
2912
- for (const word of Object.keys(moreWords)) {
2913
- if (!configWords[word]) {
2914
- configWords[word] = []
3095
+ if (key === 'trie') {
3096
+ const configTrie = this.config.trie
3097
+ const morePatterns = more.trie
3098
+ for (const pattern of morePatterns) {
3099
+ if (addFirst) {
3100
+ configTrie.unshift(pattern)
3101
+ } else {
3102
+ configTrie.push(pattern)
3103
+ }
3104
+ }
3105
+ } else if (key === 'words') {
3106
+ if (more.words.literals) {
3107
+ const literals = this.config.words.literals
3108
+ const moreLiterals = more.words.literals
3109
+ for (const word of Object.keys(moreLiterals)) {
3110
+ if (!literals[word]) {
3111
+ literals[word] = []
3112
+ }
3113
+ if (addFirst) {
3114
+ literals[word] = moreLiterals[word].concat(literals[word])
3115
+ } else {
3116
+ literals[word] = literals[word].concat(moreLiterals[word])
3117
+ }
2915
3118
  }
3119
+ }
3120
+ if (more.words.patterns) {
3121
+ const patterns = this.config.words.patterns
3122
+ const morePatterns = more.words.patterns
2916
3123
  if (addFirst) {
2917
- configWords[word] = moreWords[word].concat(configWords[word])
3124
+ this.config.words.patterns = morePatterns.concat(patterns)
2918
3125
  } else {
2919
- configWords[word] = configWords[word].concat(moreWords[word])
3126
+ this.config.words.patterns = patterns.concat(morePatterns)
3127
+ }
3128
+ }
3129
+ if (more.words.hierarchy) {
3130
+ const hierarchy = this.config.words.hierarchy
3131
+ const moreHierarchy = more.words.hierarchy
3132
+ if (addFirst) {
3133
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3134
+ } else {
3135
+ this.config.words.hierarchy = hierarchy.concat(moreHierarchy)
2920
3136
  }
2921
3137
  }
2922
3138
  } else if (key === 'name') {
@@ -3027,15 +3243,30 @@ class Config {
3027
3243
  this.config[key] = value
3028
3244
  continue
3029
3245
  }
3030
- if (key === 'words') {
3031
- const configWords = this.config.words
3032
- const moreWords = more.words
3033
- for (const word of Object.keys(moreWords)) {
3034
- if (!configWords[word]) {
3035
- configWords[word] = []
3246
+ if (key === 'trie') {
3247
+ for (const pattern of more.trie) {
3248
+ this.config.trie.unshift(pattern)
3249
+ }
3250
+ } else if (key === 'words') {
3251
+ if (this.config.words.literals) {
3252
+ const literals = this.config.words.literals
3253
+ const moreLiterals = more.words.literals
3254
+ for (const word of Object.keys(moreLiterals)) {
3255
+ if (!literals[word]) {
3256
+ literals[word] = []
3257
+ }
3258
+ literals[word] = moreLiterals[word].concat(literals[word])
3036
3259
  }
3037
- // configWords[word] = configWords[word].concat(moreWords[word])
3038
- configWords[word] = moreWords[word].concat(configWords[word])
3260
+ }
3261
+ if (this.config.words.patterns) {
3262
+ const patterns = this.config.words.patterns
3263
+ const morePatterns = more.words.patterns
3264
+ this.config.words.patterns = morePatterns.concat(patterns)
3265
+ }
3266
+ if (this.config.words.hierarchy) {
3267
+ const hierarchy = this.config.words.hierarchy
3268
+ const moreHierarchy = more.words.hierarchy
3269
+ this.config.words.hierarchy = moreHierarchy.concat(hierarchy)
3039
3270
  }
3040
3271
  } else if (key === 'name') {
3041
3272
  /*