theprogrammablemind 7.5.8-beta.4 → 7.5.8-beta.41

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/config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // lookup = (name) => returns <config>
2
2
  const { Semantics, normalizeGenerator } = require('./semantics')
3
3
  const { Generators } = require('./generators')
4
- // const { uuid: uuidv4 } = require('uuidv4')
4
+ const { v4 : uuidv4 } = require('uuid');
5
5
  const client = require('../client')
6
6
  const DigraphInternal = require('./digraph_internal')
7
7
  const helpers = require('./helpers')
@@ -22,7 +22,144 @@ const indent = (string, indent) => {
22
22
  return string.replace(/^/gm, ' '.repeat(indent));
23
23
  }
24
24
 
25
- const handleBridgeProps = (config, bridge) => {
25
+ const config_toServer = (config) => {
26
+ if (config.contextual_priorities) {
27
+ config.contextual_priorities = config.contextual_priorities.map((cp) => {
28
+ return [cp.context, cp.choose]
29
+ })
30
+ }
31
+ }
32
+
33
+ const validConfigProps = (config) => {
34
+ const valid = [
35
+ 'hierarchy',
36
+ 'objects',
37
+ 'bridges',
38
+ 'operators',
39
+ 'words',
40
+ 'priorities',
41
+ 'contextual_priorities',
42
+ 'associations',
43
+ 'name',
44
+ 'version',
45
+ 'generatorp',
46
+ 'generators',
47
+ 'semantics',
48
+ 'where',
49
+ 'floaters',
50
+ 'debug',
51
+
52
+ // TODO Fix these from the test app
53
+ 'implicits',
54
+ 'convolution',
55
+ 'expected_generated',
56
+ 'expected_results',
57
+ 'skipSemantics',
58
+ 'description',
59
+ 'contexts',
60
+ 'utterances',
61
+ 'flatten',
62
+
63
+ 'namespaces',
64
+ 'eqClasses',
65
+ ]
66
+ helpers.validProps(valid, config, 'config')
67
+ }
68
+
69
+ const setupInitializerFNArgs = (config, args) => {
70
+ const aw = (word, def) => config.addWord(word, def, args.uuid)
71
+ const ag = (generator) => config.addGenerator(generator, args.uuid, config.name)
72
+ const km = (name) => config.getConfig(name)
73
+ const apis = (name) => config.getConfig(name).api
74
+
75
+ return {
76
+ ...args,
77
+ addWord: aw,
78
+ addGenerator: ag,
79
+ config: config.getPseudoConfig(args.uuid, args.currentConfig),
80
+ km,
81
+ baseConfig: config,
82
+ apis,
83
+ }
84
+ }
85
+
86
+ const contextual_priorities_toServer = (cp) => {
87
+ if (cp.context && cp.choose) {
88
+ return [cp.context, cp.choose]
89
+ }
90
+ return cp
91
+ }
92
+
93
+ const contextual_priorities_toClient = (cp) => {
94
+ if (cp.context && cp.choose) {
95
+ return cp
96
+ }
97
+ return { context: cp[0], choose: cp[1] }
98
+ }
99
+
100
+ const operatorKey_valid = (key) => {
101
+ if (
102
+ !_.isArray(key) ||
103
+ key.length != 2 ||
104
+ !_.isString(key[0]) ||
105
+ !_.isInteger(key[1]) ||
106
+ key[1] < 0
107
+ ) {
108
+
109
+ let details = ''
110
+ if (!_.isArray(key)) {
111
+ details = "Expected an array."
112
+ } else if (key.length != 2) {
113
+ details = "Expected an array of length two."
114
+ } else if (!_.isString(key[0])) {
115
+ details = "Expected element zero to be a string that is an operator id."
116
+ } else if (!_.isInteger(key[1])) {
117
+ details = "Expected element one to be a number that is an operator level."
118
+ } else if (key[1] < 0) {
119
+ details = "Expected element one to be a number that is an operator level which is greater than zero."
120
+ }
121
+ throw new Error(`${JSON.stringify(key)} is not a valid operator key. Values are of the form [<operatorId>, <operatorLevel>]. ${details}`)
122
+ }
123
+ }
124
+
125
+ const elist = (list, check, prefix) => {
126
+ for ([index, element] of list.entries()) {
127
+ try {
128
+ check(element)
129
+ } catch( e ) {
130
+ throw new Error(prefix(index, e))
131
+ }
132
+ }
133
+ }
134
+ const contextual_priorities_valid = (cps) => {
135
+ elist(cps, (cp) => contextual_priority_valid(cp), (index, e) => `contextual_priorities has an invalid contextual priority at position ${index}. ${e}`)
136
+ }
137
+
138
+ const contextual_priority_valid = (cp) => {
139
+ if (!cp.context) {
140
+ throw new Error(`The contextual priority ${JSON.stringify(cp)} is missing the "context" property. That is a list of the operator keys that are to be prioritized differently.`)
141
+ }
142
+ if (!_.isArray(cp.context)) {
143
+ throw new Error(`The contextual priority ${JSON.stringify(cp)} has an invalid "context" value. That is a list of the operator keys that are to be prioritized differently.`)
144
+ }
145
+ elist(cp.context, (element) => operatorKey_valid(element), (index, e) => `The contextual priority ${JSON.stringify(cp)} has an invalid operator key at position ${index}. ${e}`)
146
+ if (!_.isArray(cp.choose)) {
147
+ throw new Error(`The contextual priority ${JSON.stringify(cp)} has an invalid "choose" value. The value should be a list of the operators in the context to consider for prioritization.`)
148
+ }
149
+ elist(cp.choose,
150
+ (element) => {
151
+ if (!element && element !== 0) {
152
+ throw new Error(`The value should be an index into the "context" property of the operator that is to be considered for prioritization.`)
153
+ }
154
+ if (!_.isInteger(element) || element < 0 || element >= cp.context.length) {
155
+ throw new Error(`The value should be an index into the "context" property of the operator that is to be considered for prioritization. Valid values are between 0 and ${cp.context.length-1}.`)
156
+ }
157
+ },
158
+ (index, e) => `The choose property in the contextual priority ${JSON.stringify(cp)} has an invalid index at position ${index}. ${e}`
159
+ )
160
+ }
161
+
162
+ const handleBridgeProps = (config, bridge, addFirst) => {
26
163
  ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
27
164
  () => {
28
165
  if (!bridge.bridge) {
@@ -68,19 +205,29 @@ const handleBridgeProps = (config, bridge) => {
68
205
  config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
69
206
  } else {
70
207
  const word = def.word
71
- def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
208
+ def = { initial: JSON.stringify(def), id: bridge.id, word }
72
209
  config.addWordInternal(word, def)
73
210
  }
74
211
  }
75
212
  }
213
+ /*
76
214
  if (bridge.generator) {
77
- config.config.generators.unshift(bridge.generator)
215
+ if (addFirst) {
216
+ config.config.generators.unshift(bridge.generator)
217
+ } else {
218
+ config.config.generators.push(bridge.generator)
219
+ }
78
220
  }
221
+ */
79
222
  if (bridge.generators) {
80
223
  const generators = [...bridge.generators]
81
224
  generators.reverse()
82
225
  for (let generator of generators) {
83
- config.config.generators.unshift(generator)
226
+ if (addFirst) {
227
+ config.config.generators.unshift(generator)
228
+ } else {
229
+ config.config.generators.push(generator)
230
+ }
84
231
  }
85
232
  }
86
233
  if (bridge.generatorpr) {
@@ -91,66 +238,76 @@ const handleBridgeProps = (config, bridge) => {
91
238
  const match = bridge.generatorp.match || (() => true)
92
239
  const apply = typeof bridge.generatorp == 'function' ? bridge.generatorp : bridge.generatorp.apply || bridge.generatorp
93
240
  const level = bridge.generatorp.level >= 0 ? bridge.generatorp.level : bridge.level + 1
94
- config.config.generators.unshift({
241
+
242
+ const generator = {
95
243
  where: bridge.generatorp.where || bridge.where || client.where(4),
96
244
  match: (args) => bridge.id == args.context.marker && args.context.level == level && args.context.paraphrase && match(args),
97
245
  apply: (args) => apply(args),
98
246
  applyWrapped: apply,
99
247
  property: 'generatorp',
100
- })
248
+ }
249
+ if (addFirst) {
250
+ config.config.generators.unshift(generator)
251
+ } else {
252
+ config.config.generators.push(generator)
253
+ }
254
+
101
255
  }
102
256
  if (bridge.generatorr) {
103
257
  const match = bridge.generatorr.match || (() => true)
104
258
  const apply = typeof bridge.generatorr == 'function' ? bridge.generatorr : bridge.generatorr.apply || bridge.generatorr
105
259
  const level = bridge.generatorr.level >= 0 ? bridge.generatorr.level : bridge.level + 1
106
- config.config.generators.unshift({
260
+ const generator = {
107
261
  where: bridge.generatorr.where || bridge.where || client.where(4),
108
262
  match: (args) => bridge.id == args.context.marker && args.context.level == level && !args.context.paraphrase && (args.context.response || args.context.isResponse) && match(args),
109
263
  apply: (args) => apply(args),
110
264
  applyWrapped: apply,
111
265
  property: 'generatorr',
112
- })
113
- }
114
- /*
115
- if (bridge.generatorr) {
116
- config.config.generators.unshift({
117
- // TODO merge response and isResponse
118
- where: bridge.generatorr.where || bridge.where || client.where(3),
119
- match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
120
- apply: (args) => bridge.generatorr(args),
121
- applyWrapped: bridge.generatorr,
122
- property: 'generatorr',
123
- })
266
+ }
267
+ if (addFirst) {
268
+ config.config.generators.unshift(generator)
269
+ } else {
270
+ config.config.generators.push(generator)
271
+ }
124
272
  }
125
- */
126
273
  if (bridge.evaluator) {
127
- config.config.semantics.unshift({
274
+ const semantic = {
128
275
  where: bridge.evaluator.where || bridge.where || client.where(3),
129
276
  match: ({context}) => bridge.id == context.marker && context.evaluate,
130
277
  apply: (args) => bridge.evaluator(args),
131
278
  applyWrapped: bridge.evaluator,
132
279
  property: 'evaluator',
133
- })
280
+ }
281
+ if (addFirst) {
282
+ config.config.semantics.unshift(semantic)
283
+ } else {
284
+ config.config.semantics.push(semantic)
285
+ }
134
286
  }
135
287
  if (bridge.semantic) {
136
- config.config.semantics.unshift({
288
+ const semantic = {
137
289
  where: bridge.semantic.where || bridge.where || client.where(3),
138
290
  match: ({context}) => bridge.id == context.marker,
139
291
  apply: (args) => bridge.semantic(args),
140
292
  applyWrapped: bridge.semantic,
141
293
  property: 'semantic',
142
- })
294
+ }
295
+ if (addFirst) {
296
+ config.config.semantics.unshift(semantic)
297
+ } else {
298
+ config.config.semantics.push(semantic)
299
+ }
143
300
  }
144
301
  }
145
302
  )
146
303
  }
147
304
 
148
- const handleCalculatedProps = (baseConfig, moreConfig) => {
149
- for (let bridge of moreConfig.bridges) {
305
+ const handleCalculatedProps = (baseConfig, moreConfig, addFirst) => {
306
+ for (let bridge of (moreConfig.bridges || [])) {
150
307
  const valid = [ 'after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
151
- 'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where' ]
308
+ 'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid' ]
152
309
  helpers.validProps(valid, bridge, 'bridge')
153
- handleBridgeProps(baseConfig, bridge)
310
+ handleBridgeProps(baseConfig, bridge, addFirst)
154
311
  }
155
312
  if (moreConfig.operators) {
156
313
  moreConfig.operators = moreConfig.operators.map((operator) => {
@@ -171,6 +328,10 @@ if (runtime.process.env.DEBUG_PRIORITY) {
171
328
  global.entodictonDebugPriority = JSON.parse(runtime.process.env.DEBUG_PRIORITY)
172
329
  }
173
330
 
331
+ if (runtime.process.env.DEBUG_CONTEXTUAL_PRIORITY) {
332
+ global.entodictonDebugContextualPriority = JSON.parse(runtime.process.env.DEBUG_CONTEXTUAL_PRIORITY)
333
+ }
334
+
174
335
  if (runtime.process.env.DEBUG_ASSOCIATION) {
175
336
  global.entodictonDebugAssociation = JSON.parse(runtime.process.env.DEBUG_ASSOCIATION)
176
337
  }
@@ -252,6 +413,14 @@ const normalizeConfig = (config) => {
252
413
  }
253
414
  }
254
415
  }
416
+
417
+ if (config.semantics) {
418
+ for (let semantic of config.semantics) {
419
+ if (semantic.oneShot) {
420
+ semantic.id = uuid()
421
+ }
422
+ }
423
+ }
255
424
  }
256
425
  }
257
426
 
@@ -459,8 +628,8 @@ const multiApiImpl = (initializer) => {
459
628
  initializer(config, api)
460
629
  const name = api.getName()
461
630
  multiApi.apis[name] = api
462
- api.objects = config.get('objects')
463
- api.config = () => config
631
+ // api.objects = config.get('objects')
632
+ // api.config = () => config
464
633
  multiApi.current = name
465
634
  },
466
635
 
@@ -471,11 +640,13 @@ const multiApiImpl = (initializer) => {
471
640
  }
472
641
  },
473
642
 
643
+ /*
474
644
  set objects (value) {
475
645
  for (const key in Object.keys(this.apis)) {
476
646
  this.apis[key].objects = value
477
647
  }
478
648
  },
649
+ */
479
650
 
480
651
  // "product1": apiInstance(testData1),
481
652
  apis: {
@@ -489,6 +660,46 @@ const multiApiImpl = (initializer) => {
489
660
 
490
661
  class Config {
491
662
 
663
+ toServer (config) {
664
+ return config_toServer(config)
665
+ }
666
+
667
+ base () {
668
+ const base = new Config()
669
+ for (let km of this.configs.reverse()) {
670
+ if (km.isSelf) {
671
+ continue
672
+ }
673
+ base.add(km.config)
674
+ }
675
+ return base
676
+ }
677
+
678
+ getPseudoConfig (uuid, config) {
679
+ return {
680
+ description: "this is a pseudo config that has limited functionality due to being available in the initializer function context",
681
+ addAssociation: (...args) => this.addAssociation(...args),
682
+ addAssociations: (...args) => this.addAssociations(...args),
683
+ addBridge: (...args) => this.addBridge(...args, uuid),
684
+ addContextualPriority: (...args) => this.addContextualPriority(...args),
685
+ addGenerator: (...args) => this.addGenerator(...args, uuid, config.name),
686
+ addHierarchy: (...args) => this.addHierarchy(...args),
687
+ addOperator: (...args) => this.addOperator(...args, uuid),
688
+ addPriorities: (...args) => this.addPriorities(...args),
689
+ addSemantic: (...args) => this.addSemantic(...args, uuid, config.name),
690
+ removeSemantic: (...args) => this.removeSemantic(...args, uuid, config.name),
691
+ addWord: (...args) => this.addWord(...args, uuid),
692
+
693
+ getHierarchy: (...args) => this.config.hierarchy,
694
+ getBridges: (...args) => this.config.bridges,
695
+
696
+ addArgs: (...args) => this.addArgs(...args),
697
+ getBridge: (...args) => this.getBridge(...args),
698
+ fragment: (...args) => this.fragment(...args),
699
+ addAPI: (...args) => this.addAPI(...args),
700
+ }
701
+ }
702
+
492
703
  inDevelopmentMode (call) {
493
704
  config.developmentModeOn += 1
494
705
  try {
@@ -527,9 +738,6 @@ class Config {
527
738
  }
528
739
 
529
740
  setTestConfig(testConfig) {
530
- if (this.name == 'ui') {
531
- console.log('ui setting testConfig')
532
- }
533
741
  this.testConfig = testConfig
534
742
  }
535
743
 
@@ -548,6 +756,7 @@ class Config {
548
756
  },
549
757
  eqClasses: [],
550
758
  priorities: [], // Done
759
+ contextual_priorities: [],
551
760
  version: '3',
552
761
  debug: false,
553
762
  associations: { // Done
@@ -586,6 +795,7 @@ class Config {
586
795
  'namespaces',
587
796
  'eqClasses',
588
797
  'priorities',
798
+ 'contextual_priorities',
589
799
  'associations',
590
800
  'words',
591
801
  'floaters',
@@ -724,6 +934,10 @@ class Config {
724
934
  const templateFragments = (template.fragments || []).concat(this.dynamicFragments).map( toCanonical )
725
935
  const sameFragments = helpers.safeEquals(templateFragments, instanceFragments)
726
936
  const sameQueries = helpers.safeEquals((template.queries || []).map(helpers.updateQueries), (instance.queries || []))
937
+ if (!(instance && sameQueries && sameFragments)) {
938
+ console.log("sameFragments", sameFragments)
939
+ console.log("sameQueries", sameQueries)
940
+ }
727
941
  return !(instance && sameQueries && sameFragments)
728
942
  }
729
943
 
@@ -739,6 +953,12 @@ class Config {
739
953
  }
740
954
  }
741
955
 
956
+ toData (data) {
957
+ Object.assign(data, this.config)
958
+ config_toServer(data)
959
+ }
960
+
961
+ // loadTemplate
742
962
  load (template, instance, options = { rebuild: false } ) {
743
963
  this.validifyTemplate(template)
744
964
  instance.template = template
@@ -750,7 +970,7 @@ class Config {
750
970
  // TODO fix beforeQuery
751
971
  template = { fragments: [], queries: [], ...template }
752
972
  template.fragments = template.fragments.concat(this.dynamicFragments)
753
- client.build({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
973
+ client.rebuildTemplate({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
754
974
  } else {
755
975
  // no change
756
976
  // this.initInstances.push({ ...instance, name: config.name })
@@ -768,7 +988,7 @@ class Config {
768
988
  instance.name = this.name
769
989
  this.initInstances.push(instance)
770
990
  this.instances.push(instance)
771
- client.processInstance(this, instance)
991
+ client.loadInstance(this, instance)
772
992
  }
773
993
  }
774
994
  }
@@ -825,6 +1045,22 @@ class Config {
825
1045
  this._delta.json.priorities.push({ action: 'add', priorities })
826
1046
  }
827
1047
 
1048
+ // [ operators: <list of [id, level]>, select: <index of prioritized operator> ]
1049
+ addContextualPriority(contextual_priority) {
1050
+ if (!this.config.contextual_priorities) {
1051
+ this.config.contextual_priorities = []
1052
+ }
1053
+ if (global.entodictonDebugContextualPriority) {
1054
+ if (helpers.safeEquals(entodictonDebugContextualPriority, contextual_priorities)) {
1055
+ debugger; // debug hierarchy hit
1056
+ }
1057
+ }
1058
+ contextual_priority_valid(contextual_priority)
1059
+ this.config.contextual_priorities.push(contextual_priority)
1060
+ const cpServer = contextual_priorities_toServer(contextual_priority)
1061
+ this._delta.json.contextual_priorities.push({ action: 'add', contextual_priority: cpServer })
1062
+ }
1063
+
828
1064
  addHierarchy (child, parent) {
829
1065
  if (child && parent || !child || Array.isArray(child) || (typeof child == 'string' && !parent)) {
830
1066
  this.addHierarchyChildParent(child, parent)
@@ -881,15 +1117,19 @@ class Config {
881
1117
  }
882
1118
 
883
1119
  getBridge (id, level) {
884
- return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1120
+ if (level) {
1121
+ return this.config.bridges.find( (bridge) => bridge.id == id && bridge.level == level )
1122
+ } else {
1123
+ return this.config.bridges.find( (bridge) => bridge.id == id)
1124
+ }
885
1125
  }
886
1126
 
887
- addBridge (bridge) {
1127
+ addBridge (bridge, uuid) {
888
1128
  if (!this.config.bridges) {
889
1129
  this.config.bridges = []
890
1130
  }
891
1131
  const bridges = this.config.bridges
892
- const def = Object.assign({}, bridge, { uuid: this._uuid })
1132
+ const def = Object.assign({}, bridge, { uuid: uuid || this._uuid })
893
1133
 
894
1134
  if (global.entodictonDebugBridge) {
895
1135
  if (global.entodictonDebugBridge[0] == bridge.id && global.entodictonDebugBridge[1] == bridge.level) {
@@ -911,12 +1151,7 @@ class Config {
911
1151
  this._delta.json.bridges.push({ action: 'add', bridge: def })
912
1152
  }
913
1153
 
914
- addGenerator (match, apply) {
915
- let generator = match
916
- if ((typeof match === 'function') && (typeof apply === 'function')) {
917
- generator = { match, apply }
918
- }
919
-
1154
+ addGenerator (generator, uuid, name) {
920
1155
  if (!(typeof generator.match === 'function')) {
921
1156
  throw new Error('addGenerator: Expected matcher to be a function')
922
1157
  }
@@ -933,20 +1168,16 @@ class Config {
933
1168
  }
934
1169
 
935
1170
  const generators = this.config.generators
936
- Object.assign(generator, { uuid: this._uuid, km: this.name, index: generators.length })
1171
+ Object.assign(generator, { uuid: uuid || this._uuid, km: name || this.name, index: generators.length })
937
1172
  // used to be unshift
938
1173
  generators.unshift(generator)
939
1174
  }
940
1175
 
941
- addSemantic (match, apply) {
942
- let semantic = match
943
- if ((typeof match === 'function') && (typeof apply === 'function')) {
944
- semantic = { match, apply }
945
- }
946
-
1176
+ addSemantic (semantic, uuid, name) {
947
1177
  if (!(typeof semantic.match === 'function')) {
948
1178
  throw new Error('addSemantic: Expected match to be a function')
949
1179
  }
1180
+
950
1181
  if (!(typeof semantic.apply === 'function')) {
951
1182
  throw new Error('addSemantic: Expected apply to be a function')
952
1183
  }
@@ -960,11 +1191,18 @@ class Config {
960
1191
  }
961
1192
 
962
1193
  const semantics = this.config.semantics
963
- Object.assign(semantic, { uuid: this._uuid, km: this.name, index: semantics.length })
1194
+ Object.assign(semantic, { uuid: uuid || semantic.uuid || this._uuid, km: name || this.name, index: semantics.length, id: semantic.id || uuidv4() })
964
1195
  semantics.unshift(semantic)
965
1196
  }
966
1197
 
967
- addOperator (objectOrPattern) {
1198
+ removeSemantic(deleteSemantic) {
1199
+ const index = this.config.semantics.findIndex( (semantic) => semantic.id === deleteSemantic.id )
1200
+ if (index >= 0) {
1201
+ this.config.semantics.splice(index, 1)
1202
+ }
1203
+ }
1204
+
1205
+ addOperator (objectOrPattern, uuid) {
968
1206
  if (!this.config.operators) {
969
1207
  this.config.operators = []
970
1208
  }
@@ -973,9 +1211,9 @@ class Config {
973
1211
 
974
1212
  let operator;
975
1213
  if (typeof objectOrPattern === 'string') {
976
- operator = { pattern: objectOrPattern, uuid: this._uuid }
1214
+ operator = { pattern: objectOrPattern, uuid: uuid || this._uuid }
977
1215
  } else {
978
- operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
1216
+ operator = Object.assign({}, objectOrPattern, { uuid: uuid || this._uuid })
979
1217
  }
980
1218
 
981
1219
  if (global.entodictonDebugOperator) {
@@ -996,16 +1234,16 @@ class Config {
996
1234
  this._delta.json.operators.push({ action: 'add', operator })
997
1235
  }
998
1236
 
999
- addWord (word, def) {
1000
- this.addWordInternal(word, def)
1237
+ addWord (word, def, uuid) {
1238
+ this.addWordInternal(word, def, uuid)
1001
1239
  }
1002
1240
 
1003
- addWordInternal (word, def) {
1241
+ addWordInternal (word, def, uuid) {
1004
1242
  if (!this.config.words) {
1005
1243
  this.config.words = {}
1006
1244
  }
1007
1245
  const words = this.config.words
1008
- def = Object.assign({}, def, { uuid: this._uuid })
1246
+ def = Object.assign({}, def, { uuid: uuid || this._uuid })
1009
1247
  if (words[word]) {
1010
1248
  if (!words[word].some((e) => helpers.safeEquals(e, def))) {
1011
1249
  words[word].unshift(def)
@@ -1226,33 +1464,7 @@ class Config {
1226
1464
  }
1227
1465
 
1228
1466
  if (config) {
1229
- const valid = [
1230
- 'hierarchy',
1231
- 'objects',
1232
- 'bridges',
1233
- 'operators',
1234
- 'words',
1235
- 'priorities',
1236
- 'associations',
1237
- 'name',
1238
- 'version',
1239
- 'generators',
1240
- 'semantics',
1241
- 'floaters',
1242
- 'debug',
1243
-
1244
- // TODO Fix these from the test app
1245
- 'implicits',
1246
- 'convolution',
1247
- 'expected_generated',
1248
- 'expected_results',
1249
- 'skipSemantics',
1250
- 'description',
1251
- 'contexts',
1252
- 'utterances',
1253
- 'flatten',
1254
- ]
1255
- helpers.validProps(valid, config, 'config')
1467
+ validConfigProps(config)
1256
1468
 
1257
1469
  config.operators = config.operators || []
1258
1470
  config.bridges = config.bridges || []
@@ -1262,6 +1474,7 @@ class Config {
1262
1474
  config.hierarchy = config.hierarchy || []
1263
1475
  config.associations = config.associations || { negative: [], positive: [] }
1264
1476
  config.priorities = config.priorities || []
1477
+ config.contextual_priorities = config.contextual_priorities || []
1265
1478
  }
1266
1479
 
1267
1480
  this.maxDepth = 20 // for generators and semantics
@@ -1315,6 +1528,10 @@ class Config {
1315
1528
  }
1316
1529
  }
1317
1530
 
1531
+ if (config && config.contextual_priorities) {
1532
+ contextual_priorities_valid(config.contextual_priorities)
1533
+ }
1534
+
1318
1535
  normalizeConfig(config)
1319
1536
 
1320
1537
  // set the default server so stuff just works
@@ -1330,7 +1547,6 @@ class Config {
1330
1547
  if (config) {
1331
1548
  this.name = config.name
1332
1549
  }
1333
- this.motivations = []
1334
1550
  this.loadOrder = new DigraphInternal()
1335
1551
  this.wasInitialized = false
1336
1552
  this.configs = []
@@ -1385,7 +1601,10 @@ class Config {
1385
1601
  }
1386
1602
 
1387
1603
  delta () {
1388
- return { cacheKey: this._delta.cacheKey, json: this._delta.json }
1604
+ return {
1605
+ cacheKey: this._delta.cacheKey,
1606
+ json: this._delta.json
1607
+ }
1389
1608
  }
1390
1609
 
1391
1610
  resetDelta (cacheKey) {
@@ -1397,6 +1616,7 @@ class Config {
1397
1616
  bridges: [],
1398
1617
  associations: [],
1399
1618
  priorities: [],
1619
+ contextual_priorities: [],
1400
1620
  hierarchy: [],
1401
1621
  }
1402
1622
  }
@@ -1431,11 +1651,13 @@ class Config {
1431
1651
  this._api.add(this, this._api, value)
1432
1652
  } else {
1433
1653
  this._api = _.cloneDeep(value)
1654
+ /*
1434
1655
  if (this._api) {
1435
- this._api.objects = this.config.objects
1436
- this._api.config = () => this
1437
- this._api.uuid = this._uuid
1656
+ // this._api.objects = this.config.objects
1657
+ // this._api.config = () => this
1658
+ // this._api.uuid = this._uuid
1438
1659
  }
1660
+ */
1439
1661
  this.rebuild()
1440
1662
  }
1441
1663
  }
@@ -1478,40 +1700,6 @@ class Config {
1478
1700
  // this.valid() init was not run because the kms are not all setup yet
1479
1701
  }
1480
1702
 
1481
- // motivation === { match, apply, uuid }
1482
- addMotivation (motivation) {
1483
- if (!motivation.uuid) {
1484
- motivation.uuid = this.uuid
1485
- }
1486
- this.motivations.push(motivation)
1487
- }
1488
-
1489
- resetMotivations () {
1490
- this.motivations = []
1491
- }
1492
-
1493
- doMotivations (args, context) {
1494
- args = Object.assign({}, args, { context, api: this.api })
1495
- // console.log('src/config doMotivations this.uuid', this.uuid)
1496
- // args.objects = args.getObjects(this.uuid)
1497
- const motivations = this.motivations
1498
- this.motivations = []
1499
- let done = false
1500
- for (const motivation of motivations) {
1501
- args.objects = args.getObjects(motivation.uuid)
1502
- if (!done && motivation.match(args)) {
1503
- motivation.apply(args)
1504
- if (args.context.controlKeepMotivation || motivation.repeat) {
1505
- this.motivations.push(motivation)
1506
- }
1507
- done = true
1508
- } else {
1509
- this.motivations.push(motivation)
1510
- }
1511
- }
1512
- return done
1513
- }
1514
-
1515
1703
  // TODO add more details
1516
1704
  equal(config) {
1517
1705
  if (JSON.stringify(this.config) != JSON.stringify(config.config)) {
@@ -1525,6 +1713,9 @@ class Config {
1525
1713
  runtime.fs.writeFileSync(fn, JSON.stringify(this.config, 0, 2))
1526
1714
  }
1527
1715
 
1716
+ copy (options = { callInitializers: true }) {
1717
+ }
1718
+
1528
1719
  copy (options = { callInitializers: true }) {
1529
1720
  this.valid()
1530
1721
  const cp = new Config()
@@ -1534,15 +1725,14 @@ class Config {
1534
1725
  cp.transitoryMode = this.transitoryMode
1535
1726
  cp.configs = this.configs.map((km) => km.copy2(Object.assign({}, options, { getCounter: (name) => cp.getCounter(name), callInitializers: false })))
1536
1727
  cp._uuid = cp.configs[0]._uuid
1728
+ // update uuid here set the uuid in the objects and add error checking
1537
1729
  cp.initializerFn = this.initializerFn
1538
- cp.initAfterApi = this.initAfterApi
1539
1730
  cp._api = _.cloneDeep(this._api)
1540
1731
  cp._namespace = this._namespace
1541
1732
  cp._eqClasses = this._eqClasses
1542
1733
  cp.name = this.name
1543
1734
  cp.description = this.description
1544
1735
  cp.tests = this.tests
1545
- cp.motivations = [...this.motivations]
1546
1736
  cp.isModule = this.isModule
1547
1737
  cp.loadedForTesting = this.loadedForTesting
1548
1738
  cp.initInstances = this.initInstances.slice()
@@ -1567,25 +1757,38 @@ class Config {
1567
1757
  }
1568
1758
  cp.mapUUIDs(map)
1569
1759
 
1760
+ if (cp._uuid == 'concept2') {
1761
+ // debugger
1762
+ }
1570
1763
  if (options.callInitializers) {
1571
1764
  cp.rebuild(options)
1572
- }
1573
- if (cp._api) {
1574
- cp._api.objects = cp.config.objects
1575
- cp._api.config = () => (cp instanceof Config) ? cp : cp.config
1576
- cp._api.uuid = cp._uuid
1577
- }
1765
+ } else {
1766
+ // this mess is for duplicate into a KM after resetToOne was called
1767
+ /*
1768
+ if (cp._api) {
1769
+ // cp._api.objects = cp.config.objects
1770
+ // cp._api.config = () => (cp instanceof Config) ? cp : cp.config
1771
+ // cp._api.uuid = cp._uuid
1772
+ }
1773
+ */
1578
1774
 
1579
- if (!cp.config.objects) {
1580
- cp.config.objects = { namespaced: {} }
1581
- } else if (!cp.config.objects.namespaced) {
1582
- cp.config.objects.namespaced = {}
1775
+ if (!cp.config.objects) {
1776
+ cp.config.objects = { namespaced: {} }
1777
+ } else if (!cp.config.objects.namespaced) {
1778
+ cp.config.objects.namespaced = {}
1779
+ }
1780
+ cp.configs.forEach((km) => {
1781
+ // const namespace = km.namespace
1782
+ cp.config.objects.namespaced[km._uuid] = {}
1783
+ })
1784
+ /*
1785
+ if (cp._uuid == 'concept2') {
1786
+ if (!cp.api.objects.defaultTypesForHierarchy) {
1787
+ debugger
1788
+ }
1789
+ }
1790
+ */
1583
1791
  }
1584
- cp.configs.forEach((km) => {
1585
- // const namespace = km.namespace
1586
- cp.config.objects.namespaced[km._uuid] = {}
1587
- })
1588
-
1589
1792
  cp.valid()
1590
1793
  return cp
1591
1794
  }
@@ -1685,38 +1888,33 @@ class Config {
1685
1888
  }
1686
1889
  */
1687
1890
  const objects = {}
1688
- const km = (name) => this.getConfig(name)
1689
1891
  if (config instanceof Config) {
1690
- // const aw = addWord(this.config, config.uuid)
1691
- const aw = (word, def) => this.addWord(word, def)
1692
1892
  this.get('objects').namespaced[config._uuid] = objects
1893
+ /*
1693
1894
  if (config._api) {
1694
- config._api.objects = objects
1695
- config._api.config = () => this
1895
+ // config._api.objects = objects
1896
+ // config._api.config = () => this
1696
1897
  }
1697
- config.initializerFn({ addWord: aw, km, config, baseConfig: this, currentConfig: config, objects, namespace, uuid, api: config.api })
1898
+ */
1899
+ config.initializerFn(setupInitializerFNArgs(this, { testConfig: config, currentConfig: config, objects, namespace, uuid }))
1698
1900
  } else {
1699
- // const aw = addWord(this.config, this.uuid)
1700
- const aw = (word, def) => this.addWord(word, def)
1701
1901
  this.get('objects').namespaced[this._uuid] = objects
1902
+ /*
1702
1903
  if (config._api) {
1703
- config._api.objects = objects
1704
- config._api.config = () => this
1904
+ // config._api.objects = objects
1905
+ // config._api.config = () => this
1705
1906
  }
1706
- this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects, namespace, uuid, api: this.api })
1907
+ */
1908
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, namespace, uuid }))
1707
1909
  }
1708
1910
  })
1709
- this.instances.forEach((instance) => client.processInstance(this, instance))
1911
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
1710
1912
  }
1711
1913
 
1712
1914
  initialize ({ force = true } = {}) {
1713
1915
  if (force || !this.wasInitialized) {
1714
- // const aw = addWord(this.config, this.uuid)
1715
- const aw = (word, def) => this.addWord(word, def)
1716
- const km = (name) => this.getConfig(name)
1717
- // this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects: this.get('objects'), uuid: this._uuid, namespace: '', api: this.api })
1718
1916
  const objects = this.config.objects.namespaced[this._uuid]
1719
- this.initializerFn({ addWord: aw, km, config: this, baseConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '', api: this.api })
1917
+ this.initializerFn(setupInitializerFNArgs(this, { testConfig: this, currentConfig: this, objects, uuid: this._uuid, namespace: '' }))
1720
1918
  this.wasInitialized = true
1721
1919
  }
1722
1920
  }
@@ -1724,29 +1922,22 @@ class Config {
1724
1922
  initializer (fn, options = {}) {
1725
1923
  if (options) {
1726
1924
  for (let option of Object.keys(options)) {
1727
- const validOptions = ['initAfterApi']
1728
- if (!['initAfterApi'].includes(option)) {
1925
+ const validOptions = []
1926
+ if (!validOptions.includes(option)) {
1729
1927
  throw new Error(`For Config.initializer, unrecognized option ${option}. The valid options are ${validOptions}`)
1730
1928
  }
1731
1929
  }
1732
1930
  }
1733
- const { initAfterApi = false } = options;
1734
1931
  this.wasInitialized = false
1735
- this.initAfterApi = initAfterApi
1736
- this.initializerFn = (args) => {
1932
+ this.initializerFn = (args, { dontCallFn } = {}) => {
1737
1933
  const transitoryMode = global.transitoryMode
1738
1934
  global.transitoryMode = false
1739
1935
  // const baseConfig = args.baseConfig
1740
1936
  const currentConfig = args.currentConfig
1741
1937
 
1742
- if (currentConfig.api) {
1743
- currentConfig.api.objects = args.objects
1744
- // GREG42 currentConfig.api.config = () => this
1745
- currentConfig.api.config = () => args.baseConfig
1746
- currentConfig.api.uuid = currentConfig._uuid
1938
+ if (args.isAfterApi) {
1939
+ fn(args)
1747
1940
  }
1748
- // this.instances.forEach( (instance) => client.processInstance(this, instance) )
1749
- fn(args)
1750
1941
  currentConfig.wasInitialized = true
1751
1942
  global.transitoryMode = transitoryMode
1752
1943
  }
@@ -1913,7 +2104,6 @@ class Config {
1913
2104
  }
1914
2105
  this.config.objects.namespaced = {}
1915
2106
  this.resetWasInitialized()
1916
- this.resetMotivations()
1917
2107
 
1918
2108
  // reorder configs base on load ordering
1919
2109
  {
@@ -1939,8 +2129,8 @@ class Config {
1939
2129
  this.config.objects.namespaced[km._uuid] = {}
1940
2130
  const namespacedObjects = this.config.objects.namespaced[km._uuid]
1941
2131
  this.setupNamespace(km)
1942
- // const aw = addWord(km.config.config ? km.config.config : km.config, km.config.uuid)
1943
- const aw = (word, def) => this.addWord(word, def)
2132
+ // const aw = (word, def) => this.addWord(word, def)
2133
+ // const ag = (matchOrGenerator, applyOrNothing) => this.addGenerator(matchOrGenerator, applyOrNothing)
1944
2134
  let config = km.config
1945
2135
 
1946
2136
  if (config.addedArgss) {
@@ -1961,45 +2151,51 @@ class Config {
1961
2151
  }
1962
2152
  config.wasInitialized = false
1963
2153
  // TODO change name of config: to baseConfig:
1964
- const kmFn = (name) => this.getConfig(name)
2154
+ const kmFn = (name) => {
2155
+ const config = this.getConfig(name)
2156
+ return config
2157
+ }
1965
2158
  // const hierarchy = new DigraphInternal((config.config || {}).hierarchy)
1966
- const args = {
2159
+ const args = new Object(setupInitializerFNArgs(this, {
1967
2160
  isModule,
1968
- addWord: aw,
1969
- km: kmFn,
1970
2161
  hierarchy: this.hierarchy,
1971
- config,
1972
- baseConfig: this,
2162
+ testConfig: config,
1973
2163
  currentConfig: config,
1974
2164
  uuid: config._uuid,
1975
2165
  objects: namespacedObjects,
1976
2166
  namespace,
1977
- motivation: (m) => config.addMotivation(m),
1978
- api: config.api
2167
+ api: config.api,
2168
+ }))
2169
+
2170
+ const currentConfig = args.currentConfig
2171
+
2172
+ /*
2173
+ if (args.currentConfig.api) {
2174
+ // args.currentConfig.api.objects = args.objects
2175
+ // TODO assign pseudo config?
2176
+ // args.currentConfig.api.config = () => args.baseConfig
2177
+ // args.currentConfig.api.uuid = args.currentConfig._uuid
2178
+ args.currentConfig.wasInitialized = true
1979
2179
  }
1980
- config.initializerFn(args)
1981
- if (config.initAfterApi) {
1982
- // reverse the list
2180
+ */
2181
+ // debugger
2182
+ // greg55
2183
+ config.initializerFn(args, { dontCallFn: true })
1983
2184
  initAfterApis.unshift({ config, args })
1984
- } else {
1985
- if (interleaved) {
1986
- initAfterApis.unshift(null)
1987
- }
1988
- }
1989
- // greg
1990
2185
  if (config._api) {
1991
2186
  if (config._api.initialize) {
1992
2187
  // reverse the list
1993
- inits.unshift( () => config._api.initialize({ config: this, km: kmFn, api: config._api }) )
2188
+ // TODO sync up the args with initialize of config
2189
+ inits.unshift( () => config._api.initialize({ config: this, km: kmFn, ...args, api: config._api }) )
1994
2190
  // config._api.initialize({ config, api: config._api })
1995
2191
  } else {
1996
2192
  if (interleaved) {
1997
2193
  inits.unshift(null)
1998
2194
  }
1999
2195
  }
2000
- config._api.objects = namespacedObjects
2001
- config._api.config = () => this
2002
- config._api.uuid = config._uuid
2196
+ // config._api.objects = namespacedObjects
2197
+ // config._api.config = () => this
2198
+ // config._api.uuid = config._uuid
2003
2199
  } else {
2004
2200
  if (interleaved) {
2005
2201
  inits.unshift(null)
@@ -2041,16 +2237,16 @@ class Config {
2041
2237
  init()
2042
2238
  }
2043
2239
  for (let init of initAfterApis) {
2044
- // init.args.isAfterApi = true
2045
2240
  init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
2046
2241
  }
2047
- this.instances.forEach((instance) => client.processInstance(this, instance))
2242
+ this.instances.forEach((instance) => client.loadInstance(this, instance))
2048
2243
  } else {
2049
2244
  const base = {
2050
2245
  operators: this.config.operators,
2051
2246
  bridges: this.config.bridges,
2052
2247
  hierarchy: this.config.hierarchy,
2053
2248
  priorities: this.config.priorities,
2249
+ contextual_priorities: this.config.contextual_priorities,
2054
2250
  associations: this.config.associations,
2055
2251
  words: this.config.words
2056
2252
  }
@@ -2059,6 +2255,7 @@ class Config {
2059
2255
  this.config.bridges = []
2060
2256
  this.config.hierarchy = []
2061
2257
  this.config.priorities = []
2258
+ this.config.contextual_priorities = []
2062
2259
  this.config.associations = { positive: [], negative: [] }
2063
2260
  this.config.words = {}
2064
2261
 
@@ -2073,19 +2270,19 @@ class Config {
2073
2270
  }
2074
2271
  // console.log('name -------------', name)
2075
2272
  if (inits[i]) {
2273
+ // greg55
2076
2274
  inits[i]()
2077
2275
  }
2078
2276
  if (initAfterApis[i]) {
2079
2277
  const init = initAfterApis[i]
2080
- init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true })
2278
+ init.config.initializerFn({ ...init.args, kms: this.getConfigs(), isAfterApi: true})
2081
2279
  }
2082
2280
  const instance = this.instances.find((instance) => instance.name == name)
2083
2281
  if (instance) {
2084
- client.processInstance(this, instance)
2282
+ client.loadInstance(this, instance)
2085
2283
  }
2086
2284
  this.hierarchy.edges = this.config.hierarchy
2087
2285
  }
2088
- // this.instances.forEach((instance) => client.processInstance(this, instance))
2089
2286
  }
2090
2287
 
2091
2288
  if (reverseIt) {
@@ -2208,13 +2405,9 @@ class Config {
2208
2405
  }
2209
2406
  const km = (name) => this.getConfig(name)
2210
2407
  if (config instanceof Config) {
2211
- // const aw = addWord(this.config, config.uuid)
2212
- const aw = (word, def) => this.addWord(word, def)
2213
- config.initializerFn({ isModule: this.isModule, addWord: aw, baseConfig: this, km, currentConfig: config, config, objects: nsobjects, namespace, uuid, api: config.api })
2408
+ config.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: config, testConfig: config, objects: nsobjects, namespace, uuid }))
2214
2409
  } else {
2215
- // const aw = addWord(this.config, this.uuid)
2216
- const aw = (word, def) => this.addWord(word, def)
2217
- this.initializerFn({ isModule: this.isModule, addWord: aw, baseConfig: this, km, currentConfig: this, config: this, objects: nsobjects, namespace, uuid, api: this.api })
2410
+ this.initializerFn(setupInitializerFNArgs(this, { isModule: this.isModule, currentConfig: this, testConfig: this, objects: nsobjects, namespace, uuid }))
2218
2411
  }
2219
2412
  })
2220
2413
  }
@@ -2279,6 +2472,20 @@ class Config {
2279
2472
  config.priorities = priorities
2280
2473
  }
2281
2474
 
2475
+ if (config.contextual_priorities) {
2476
+ let contextual_priorities = config.contextual_priorities
2477
+ contextual_priorities = contextual_priorities.map((cp) => {
2478
+ const { context, choose } = cp
2479
+ return {
2480
+ context: context.map((id) => {
2481
+ return [toNS(id[0]), id[1]]
2482
+ }),
2483
+ choose
2484
+ }
2485
+ })
2486
+ config.contextual_priorities = contextual_priorities
2487
+ }
2488
+
2282
2489
  for (const bag of bags) {
2283
2490
  if (config[bag]) {
2284
2491
  config[bag] = config[bag].map((b) => {
@@ -2473,7 +2680,8 @@ class Config {
2473
2680
  }
2474
2681
 
2475
2682
  // TODO get rid of useOldVersion arg
2476
- addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2683
+ addInternal (more, { addFirst = false, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
2684
+ validConfigProps(more)
2477
2685
  if (more instanceof Config) {
2478
2686
  more.initialize({ force: false })
2479
2687
  if (useOldVersion) {
@@ -2484,7 +2692,7 @@ class Config {
2484
2692
  }
2485
2693
  }
2486
2694
  if (hcps) {
2487
- handleCalculatedProps(this, more)
2695
+ handleCalculatedProps(this, more, addFirst)
2488
2696
  applyUUID(more, this._uuid)
2489
2697
  }
2490
2698
  for (const key of Object.keys(more)) {
@@ -2509,7 +2717,11 @@ class Config {
2509
2717
  if (!configWords[word]) {
2510
2718
  configWords[word] = []
2511
2719
  }
2512
- configWords[word] = configWords[word].concat(moreWords[word])
2720
+ if (addFirst) {
2721
+ configWords[word] = moreWords[word].concat(configWords[word])
2722
+ } else {
2723
+ configWords[word] = configWords[word].concat(moreWords[word])
2724
+ }
2513
2725
  }
2514
2726
  } else if (key === 'name') {
2515
2727
  /*
@@ -2571,13 +2783,17 @@ class Config {
2571
2783
  this.config[key].splice(iOldOne, 1)
2572
2784
  break;
2573
2785
  }
2574
- }
2786
+ }
2575
2787
  }
2576
2788
  }
2577
2789
  }
2578
2790
  // console.log('key', key, 'XXX')
2579
2791
  // console.log('more', JSON.stringify(more, null, 2))
2580
- this.config[key] = this.config[key].concat(more[key])
2792
+ if (addFirst) {
2793
+ this.config[key] = more[key].concat(this.config[key])
2794
+ } else {
2795
+ this.config[key] = this.config[key].concat(more[key])
2796
+ }
2581
2797
  } else {
2582
2798
  if (!(key in this.config)) {
2583
2799
  throw new Error(`Unexpected property in config ${key}`)
@@ -2708,5 +2924,8 @@ class Config {
2708
2924
  }
2709
2925
 
2710
2926
  module.exports = {
2711
- Config
2927
+ Config,
2928
+ config_toServer,
2929
+ operatorKey_valid,
2930
+ handleBridgeProps,
2712
2931
  }