@suss/resolution 0.30.0 → 0.31.1

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/dist/index.cjs CHANGED
@@ -22,34 +22,55 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ANSWER_RELATIONS: () => ANSWER_RELATIONS,
24
24
  ASKING_RELATIONS: () => ASKING_RELATIONS,
25
+ BASE_CLASS_RULE: () => BASE_CLASS_RULE,
25
26
  FACT_CONTRACT_CASES: () => FACT_CONTRACT_CASES,
27
+ INSTANCE_STEP: () => INSTANCE_STEP,
26
28
  NAMESPACE_IMPORT: () => NAMESPACE_IMPORT,
27
29
  NAMESPACE_IMPORT_NAME: () => NAMESPACE_IMPORT_NAME,
30
+ NAMESPACE_MEMBER_RULE: () => NAMESPACE_MEMBER_RULE,
31
+ NO_CONTEXT: () => NO_CONTEXT,
32
+ NO_CONTEXT_NAME: () => NO_CONTEXT_NAME,
28
33
  RESOLUTION_QUESTIONS: () => RESOLUTION_QUESTIONS,
29
34
  RESOLUTION_RULES: () => RESOLUTION_RULES,
30
35
  RESULT_STEP: () => RESULT_STEP,
36
+ UNDER_ANSWER_RELATIONS: () => UNDER_ANSWER_RELATIONS,
37
+ UNDER_QUESTION_ROW_BUDGET: () => UNDER_QUESTION_ROW_BUDGET,
38
+ UNDER_RUN_ROW_BUDGET: () => UNDER_RUN_ROW_BUDGET,
31
39
  VALUE_STEP: () => VALUE_STEP,
40
+ addPackWords: () => addPackWords,
32
41
  agreedMountPrefix: () => agreedMountPrefix,
42
+ allocationSitesOf: () => allocationSitesOf,
43
+ alsoSteps: () => alsoSteps,
44
+ answersByKey: () => answersByKey,
33
45
  askResolution: () => askResolution,
46
+ askResolutionUnder: () => askResolutionUnder,
34
47
  calleeOutcomeOf: () => calleeOutcomeOf,
35
48
  calleeOutcomes: () => calleeOutcomes,
36
49
  checkFactContract: () => checkFactContract,
50
+ comesToUnder: () => comesToUnder,
37
51
  couldBeSettled: () => couldBeSettled,
38
52
  explainResolutionProof: () => explainResolutionProof,
39
53
  explainResolvedKey: () => explainResolvedKey,
54
+ isWrittenAsUnder: () => isWrittenAsUnder,
40
55
  joinMountedPath: () => joinMountedPath,
41
56
  mountPathsOf: () => mountPathsOf,
42
57
  nodeOfKey: () => nodeOfKey,
58
+ objectOfUnder: () => objectOfUnder,
43
59
  placeholderValues: () => placeholderValues,
44
60
  queryFacts: () => queryFacts,
45
61
  renderExplanation: () => renderExplanation,
46
62
  resolutionProgram: () => resolutionProgram,
63
+ resolutionUnderProgram: () => resolutionUnderProgram,
47
64
  singleAnswers: () => singleAnswers,
48
65
  startsAtName: () => startsAtName,
66
+ underQuestionSpend: () => underQuestionSpend,
49
67
  valueLeftByWrites: () => valueLeftByWrites,
50
68
  writesRunInOrder: () => writesRunInOrder,
51
69
  writtenSourcesOf: () => writtenSourcesOf,
52
- writtenValueOf: () => writtenValueOf
70
+ writtenValueOf: () => writtenValueOf,
71
+ writtenValueUnder: () => writtenValueUnder,
72
+ writtenValuesByKey: () => writtenValuesByKey,
73
+ writtenValuesOf: () => writtenValuesOf
53
74
  });
54
75
  module.exports = __toCommonJS(index_exports);
55
76
 
@@ -57,6 +78,8 @@ module.exports = __toCommonJS(index_exports);
57
78
  var import_datalog = require("@suss/datalog");
58
79
  var ASKING_RELATIONS = [
59
80
  "wanted",
81
+ "wantedUnder",
82
+ "wantedSites",
60
83
  "wantedOrigin",
61
84
  "wantedCallOrigin",
62
85
  "wantedExportsOf",
@@ -66,8 +89,12 @@ var ASKING_RELATIONS = [
66
89
  ];
67
90
  var NO_LANGUAGE_RULES = [];
68
91
  var programs = /* @__PURE__ */ new WeakMap();
69
- function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
70
- const built = programs.get(languageRules);
92
+ var underPrograms = /* @__PURE__ */ new WeakMap();
93
+ var contextFreeAnswers = () => ANSWER_RELATIONS.filter(
94
+ (relation) => !UNDER_ANSWER_RELATIONS.includes(relation)
95
+ );
96
+ function builtProgram(languageRules, cache, complete) {
97
+ const built = cache.get(languageRules);
71
98
  if (built !== void 0) {
72
99
  return built;
73
100
  }
@@ -76,10 +103,16 @@ function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
76
103
  ...languageRules,
77
104
  ...RESOLUTION_QUESTIONS
78
105
  ];
79
- const program = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? { rules, demandDriven: [], demands: [] } : (0, import_datalog.deriveOnDemand)(rules, ANSWER_RELATIONS);
80
- programs.set(languageRules, program);
106
+ const program = process.env.SUSS_RESOLUTION_ON_DEMAND === "0" ? { rules, demandDriven: [], demands: [] } : (0, import_datalog.deriveOnDemand)(rules, complete);
107
+ cache.set(languageRules, program);
81
108
  return program;
82
109
  }
110
+ function resolutionProgram(languageRules = NO_LANGUAGE_RULES) {
111
+ return builtProgram(languageRules, programs, contextFreeAnswers());
112
+ }
113
+ function resolutionUnderProgram(languageRules = NO_LANGUAGE_RULES) {
114
+ return builtProgram(languageRules, underPrograms, ANSWER_RELATIONS);
115
+ }
83
116
  function queryFacts(program) {
84
117
  if (program.demandDriven.length === 0) {
85
118
  return [];
@@ -116,6 +149,75 @@ function askResolution(db, keys, asking = "wanted", program = resolutionProgram(
116
149
  (0, import_datalog.clearRelations)(db, program.rules, forget);
117
150
  }
118
151
  }
152
+ var askedUnderByDb = /* @__PURE__ */ new WeakMap();
153
+ var UNDER_QUESTION_ROW_BUDGET = 2e7;
154
+ var UNDER_RUN_ROW_BUDGET = 4e7;
155
+ var spentUnderByDb = /* @__PURE__ */ new WeakMap();
156
+ function spendOf(db) {
157
+ let spend = spentUnderByDb.get(db);
158
+ if (spend === void 0) {
159
+ spend = { rows: 0, asked: 0, abandoned: 0, skipped: 0 };
160
+ spentUnderByDb.set(db, spend);
161
+ }
162
+ return spend;
163
+ }
164
+ function underQuestionSpend(db) {
165
+ return { ...spendOf(db) };
166
+ }
167
+ function askResolutionUnder(db, pairs, program = resolutionUnderProgram(), questionBudget = UNDER_QUESTION_ROW_BUDGET, runBudget = UNDER_RUN_ROW_BUDGET) {
168
+ let asked = askedUnderByDb.get(db);
169
+ if (asked === void 0) {
170
+ asked = /* @__PURE__ */ new Set();
171
+ askedUnderByDb.set(db, asked);
172
+ }
173
+ const fresh = [...pairs].filter(
174
+ ([key, site]) => !asked.has((0, import_datalog.tupleKey)([key, site]))
175
+ );
176
+ if (fresh.length === 0) {
177
+ return "answered";
178
+ }
179
+ const spend = spendOf(db);
180
+ for (const [key, site] of fresh) {
181
+ asked.add((0, import_datalog.tupleKey)([key, site]));
182
+ }
183
+ spend.asked += 1;
184
+ if (spend.rows >= runBudget) {
185
+ spend.skipped += 1;
186
+ (0, import_datalog.chargeQuestion)("skipped");
187
+ return "abandoned";
188
+ }
189
+ for (const [key, site] of fresh) {
190
+ db.add("wantedUnder", [key, site]);
191
+ }
192
+ const forget = queryFacts(program);
193
+ const clearDerived = () => {
194
+ if (forget.length > 0) {
195
+ (0, import_datalog.clearRelations)(db, program.rules, forget);
196
+ }
197
+ };
198
+ const budget = (0, import_datalog.rowBudget)(questionBudget);
199
+ try {
200
+ (0, import_datalog.evaluate)(db, program.rules, void 0, budget);
201
+ } catch (error) {
202
+ if (!(error instanceof import_datalog.BudgetExhausted)) {
203
+ throw error;
204
+ }
205
+ spend.rows += error.examined;
206
+ spend.abandoned += 1;
207
+ (0, import_datalog.chargeQuestion)("abandoned");
208
+ db.retract("wantedUnder", fresh);
209
+ clearDerived();
210
+ (0, import_datalog.chargeAbandoned)(
211
+ fresh.map(([key, site]) => `${key} under ${site}`).join(", "),
212
+ error.examined
213
+ );
214
+ return "abandoned";
215
+ }
216
+ spend.rows += budget.examined;
217
+ (0, import_datalog.chargeQuestion)();
218
+ clearDerived();
219
+ return "answered";
220
+ }
119
221
 
120
222
  // src/callee.ts
121
223
  var UNDECLARED = { kind: "undeclared" };
@@ -544,6 +646,12 @@ var DEFAULT_PHRASES = {
544
646
  "last write": ({ tuple, describe }) => ({
545
647
  reason: `${describe(tuple[0])} is written more than once, and the last write leaves it as ${describe(tuple[1])}`
546
648
  }),
649
+ "one of several writes": ({ tuple, describe }) => ({
650
+ reason: `${describe(tuple[0])} is written more than once, and one of those writes makes it ${describe(tuple[1])}`,
651
+ assumptions: [
652
+ `nothing says which write to ${describe(tuple[0])} ran last, so every write it has is a possible value`
653
+ ]
654
+ }),
547
655
  fallback: ({ tuple, describe }) => ({
548
656
  reason: `${describe(tuple[0])} is a fallback expression, and ${describe(tuple[1])} is the branch that resolves`
549
657
  }),
@@ -560,7 +668,7 @@ var DEFAULT_PHRASES = {
560
668
  "property read": ({ tuple, premises, describe }) => {
561
669
  const [, object, name] = premises[0].tuple;
562
670
  const contains = premises[2];
563
- const inherited = contains.kind === "derived" && contains.premises.length > 1;
671
+ const inherited = contains.kind === "derived" && (0, import_datalog2.ruleLabel)(contains.rule) === BASE_CLASS_RULE;
564
672
  return {
565
673
  reason: `${describe(tuple[0])} reads ${String(name)} off ${describe(object)}, which contains ${describe(tuple[1])}`,
566
674
  notes: inherited ? [`${String(name)} comes from a base class`] : []
@@ -639,7 +747,8 @@ var CHAIN_RELATIONS = /* @__PURE__ */ new Set([
639
747
  "isWrittenAs",
640
748
  "comesFrom",
641
749
  "reaches",
642
- "stepsTo"
750
+ "stepsTo",
751
+ "hop"
643
752
  ]);
644
753
  function inlineChain(proof, state) {
645
754
  const explained = explainResolutionProof(proof, {
@@ -695,6 +804,17 @@ function importStep(proof, state) {
695
804
  assumptions: []
696
805
  };
697
806
  }
807
+ function namespaceMemberStep(proof, state) {
808
+ const [x, module2, name] = proof.tuple;
809
+ return {
810
+ from: x,
811
+ to: module2,
812
+ rule: NAMESPACE_MEMBER_RULE,
813
+ reason: `${state.describe(x)} reads ${String(name)} off ${state.describe(module2)}, which is imported whole`,
814
+ notes: [],
815
+ assumptions: []
816
+ };
817
+ }
698
818
  var flattenInto = (proof, state) => {
699
819
  if (proof.kind === "truncated") {
700
820
  state.truncated = true;
@@ -704,7 +824,7 @@ var flattenInto = (proof, state) => {
704
824
  return;
705
825
  }
706
826
  const relation = proof.relation;
707
- if (relation === "stepsTo") {
827
+ if (relation === "stepsTo" || relation === "hop") {
708
828
  state.steps.push(stepFrom(proof, state));
709
829
  return;
710
830
  }
@@ -715,6 +835,10 @@ var flattenInto = (proof, state) => {
715
835
  return;
716
836
  }
717
837
  if (relation === "comesFrom") {
838
+ if ((0, import_datalog2.ruleLabel)(proof.rule) === NAMESPACE_MEMBER_RULE) {
839
+ state.steps.push(namespaceMemberStep(proof, state));
840
+ return;
841
+ }
718
842
  if (proof.premises.length === 2) {
719
843
  flattenInto(proof.premises[0], state);
720
844
  state.steps.push(importStep(proof.premises[1], state));
@@ -891,6 +1015,37 @@ function nodeOfKey(rootsByFile, key) {
891
1015
  return null;
892
1016
  }
893
1017
 
1018
+ // src/packWords.ts
1019
+ function addPackWords(db, words) {
1020
+ for (const word of words.givesBackOne ?? []) {
1021
+ db.add("givesBackOne", [word.base, word.method]);
1022
+ }
1023
+ for (const word of words.givesBackOneOfArgument ?? []) {
1024
+ db.add("givesBackOneOfArgument", [
1025
+ word.base,
1026
+ word.method,
1027
+ String(word.argument)
1028
+ ]);
1029
+ }
1030
+ for (const word of words.givesBackOneOfImport ?? []) {
1031
+ db.add("givesBackOneOfImport", [
1032
+ word.module,
1033
+ word.name,
1034
+ String(word.argument)
1035
+ ]);
1036
+ }
1037
+ for (const word of words.entersAsSelf ?? []) {
1038
+ db.add("entersAsSelf", [word.module, word.name]);
1039
+ }
1040
+ for (const word of words.unwrapsByName ?? []) {
1041
+ db.add("unwrapsByName", [word.callee, String(word.argument)]);
1042
+ db.add("wrapperModule", [word.callee, word.module]);
1043
+ }
1044
+ for (const word of words.associationConstructor ?? []) {
1045
+ db.add("associationConstructor", [word.module, word.name]);
1046
+ }
1047
+ }
1048
+
894
1049
  // src/session.ts
895
1050
  var import_datalog3 = require("@suss/datalog");
896
1051
  function explainResolvedKey(options) {
@@ -946,7 +1101,7 @@ function explainResolvedKey(options) {
946
1101
 
947
1102
  // src/singleAnswer.ts
948
1103
  var NO_PLACEHOLDERS = /* @__PURE__ */ new Set();
949
- function singleAnswers(rows, placeholders = NO_PLACEHOLDERS) {
1104
+ function answersByKey(rows, placeholders = NO_PLACEHOLDERS) {
950
1105
  const candidates = /* @__PURE__ */ new Map();
951
1106
  for (const row of rows) {
952
1107
  const key = String(row[0]);
@@ -958,9 +1113,15 @@ function singleAnswers(rows, placeholders = NO_PLACEHOLDERS) {
958
1113
  set.add(answer);
959
1114
  candidates.set(key, set);
960
1115
  }
961
- const settled = /* @__PURE__ */ new Map();
1116
+ const answers = /* @__PURE__ */ new Map();
962
1117
  for (const [key, set] of candidates) {
963
- const answers = withoutPlaceholders(set, placeholders);
1118
+ answers.set(key, withoutPlaceholders(set, placeholders));
1119
+ }
1120
+ return answers;
1121
+ }
1122
+ function singleAnswers(rows, placeholders = NO_PLACEHOLDERS) {
1123
+ const settled = /* @__PURE__ */ new Map();
1124
+ for (const [key, answers] of answersByKey(rows, placeholders)) {
964
1125
  if (answers.length === 1) {
965
1126
  settled.set(key, answers[0]);
966
1127
  }
@@ -978,6 +1139,28 @@ function withoutPlaceholders(answers, placeholders) {
978
1139
  return kept;
979
1140
  }
980
1141
 
1142
+ // src/underContext.ts
1143
+ function answersUnder(db, relation, key, site) {
1144
+ return db.lookup(relation, 0, key).filter((row) => String(row[1]) === site).map((row) => String(row[2]));
1145
+ }
1146
+ function isWrittenAsUnder(db, key, site) {
1147
+ return answersUnder(db, "wantedIsWrittenAsUnder", key, site);
1148
+ }
1149
+ function comesToUnder(db, key, site) {
1150
+ return answersUnder(db, "wantedComesToUnder", key, site);
1151
+ }
1152
+ function objectOfUnder(db, key, site) {
1153
+ return answersUnder(db, "wantedObjectOfUnder", key, site);
1154
+ }
1155
+ function writtenValueUnder(db, key, site) {
1156
+ const rows = isWrittenAsUnder(db, key, site).map((answer) => [key, answer]);
1157
+ const answers = answersByKey(rows, placeholderValues(db)).get(key) ?? [];
1158
+ return answers.length === 1 ? answers[0] : null;
1159
+ }
1160
+ function allocationSitesOf(db, cls) {
1161
+ return db.lookup("wantedAllocatedAt", 0, cls).map((row) => String(row[1]));
1162
+ }
1163
+
981
1164
  // src/writes.ts
982
1165
  function valueLeftByWrites(writes, ordered) {
983
1166
  const deciding = writes.filter((write) => !write.narrowsName);
@@ -1008,23 +1191,58 @@ function sharedConstruction(writes) {
1008
1191
  }
1009
1192
 
1010
1193
  // src/writtenValue.ts
1011
- function writtenValueOf(db, key, ask) {
1012
- const placeholders = placeholderValues(db);
1013
- const direct = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
1014
- key
1015
- );
1016
- if (direct === void 0) {
1017
- return null;
1194
+ var WRITTEN_AS = "wantedIsWrittenAs";
1195
+ function writtenValueOf(db, key, ask, relation = WRITTEN_AS) {
1196
+ const answers = settledByKey(db, [key], ask, relation).get(key) ?? [];
1197
+ return answers.length === 1 ? answers[0] : null;
1198
+ }
1199
+ function writtenValuesOf(db, key, ask, relation = WRITTEN_AS) {
1200
+ const settled = settledByKey(db, [key], ask, relation).get(key) ?? [];
1201
+ return settled.length > 0 ? settled : writesLeft(db, key);
1202
+ }
1203
+ function writtenValuesByKey(db, keys, ask, relation = WRITTEN_AS) {
1204
+ const one = /* @__PURE__ */ new Map();
1205
+ for (const [key, answers] of settledByKey(db, keys, ask, relation)) {
1206
+ if (answers.length === 1) {
1207
+ one.set(key, answers[0]);
1208
+ }
1018
1209
  }
1019
- const isCall = db.facts("call").some((row) => String(row[0]) === direct);
1020
- if (!isCall) {
1210
+ return one;
1211
+ }
1212
+ function settledByKey(db, keys, ask, relation) {
1213
+ const placeholders = placeholderValues(db);
1214
+ const byKey = answersByKey(db.facts(relation), placeholders);
1215
+ const direct = new Map(keys.map((key) => [key, byKey.get(key) ?? []]));
1216
+ const calls = new Set(db.facts("call").map((row) => String(row[0])));
1217
+ const throughCalls = [...direct.values()].flat().filter((answer) => calls.has(answer));
1218
+ if (throughCalls.length === 0) {
1021
1219
  return direct;
1022
1220
  }
1023
- ask([direct]);
1024
- const deeper = singleAnswers(db.facts("wantedIsWrittenAs"), placeholders).get(
1025
- direct
1221
+ ask(throughCalls);
1222
+ const deeper = singleAnswers(db.facts(relation), placeholders);
1223
+ return new Map(
1224
+ [...direct].map(([key, answers]) => [
1225
+ key,
1226
+ collapseCalls(answers, calls, deeper)
1227
+ ])
1026
1228
  );
1027
- return deeper ?? direct;
1229
+ }
1230
+ function collapseCalls(direct, calls, deeper) {
1231
+ return [
1232
+ ...new Set(
1233
+ direct.map(
1234
+ (answer) => calls.has(answer) ? deeper.get(answer) ?? answer : answer
1235
+ )
1236
+ )
1237
+ ];
1238
+ }
1239
+ function writesLeft(db, key) {
1240
+ const unstated = db.facts("writesUnstated").some((row) => String(row[0]) === key);
1241
+ if (unstated) {
1242
+ return [];
1243
+ }
1244
+ const candidates = answersByKey(db.facts("mayHold"), placeholderValues(db)).get(key) ?? [];
1245
+ return candidates.length > 1 ? candidates : [];
1028
1246
  }
1029
1247
 
1030
1248
  // src/index.ts
@@ -1032,38 +1250,61 @@ var import_datalog4 = require("@suss/datalog");
1032
1250
  var VALUE_STEP = (0, import_datalog4.constant)("value");
1033
1251
  var NAMESPACE_IMPORT_NAME = "*";
1034
1252
  var NAMESPACE_IMPORT = (0, import_datalog4.constant)(NAMESPACE_IMPORT_NAME);
1253
+ var NAMESPACE_MEMBER_RULE = "namespace member";
1254
+ var BASE_CLASS_RULE = "base class";
1255
+ var INSTANCE_STEP = (0, import_datalog4.constant)("instance");
1035
1256
  var RESULT_STEP = (0, import_datalog4.constant)("result");
1036
- var RESOLUTION_RULES = [
1257
+ var NO_CONTEXT_NAME = "none";
1258
+ var NO_CONTEXT = (0, import_datalog4.constant)(NO_CONTEXT_NAME);
1259
+ var STEP_LATTICE = [
1260
+ { soFar: VALUE_STEP, next: (0, import_datalog4.variable)("kind"), took: (0, import_datalog4.variable)("kind") },
1261
+ { soFar: INSTANCE_STEP, next: VALUE_STEP, took: INSTANCE_STEP },
1262
+ { soFar: INSTANCE_STEP, next: INSTANCE_STEP, took: INSTANCE_STEP },
1263
+ { soFar: INSTANCE_STEP, next: RESULT_STEP, took: RESULT_STEP },
1264
+ { soFar: RESULT_STEP, next: VALUE_STEP, took: RESULT_STEP },
1265
+ { soFar: RESULT_STEP, next: INSTANCE_STEP, took: RESULT_STEP },
1266
+ { soFar: RESULT_STEP, next: RESULT_STEP, took: RESULT_STEP }
1267
+ ];
1268
+ var STATED_RULES = [
1037
1269
  // Aliasing: const x = y, or an identifier referencing a declaration.
1038
1270
  // A language with a hop of its own, like JavaScript's `.bind`, states
1039
1271
  // it as a step too, or every question but `comesTo` misses it.
1040
1272
  (0, import_datalog4.rule)(
1041
- "stepsTo",
1273
+ "hop",
1042
1274
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
1043
1275
  [(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
1044
1276
  "alias"
1045
1277
  ),
1046
1278
  // A name written more than once has the value the last write left
1047
- // there. The adapter works out which write that is and stays quiet
1048
- // when control flow decides, so such a name steps nowhere at all.
1279
+ // there. The adapter works out which write that is, and stays quiet
1280
+ // when control flow decides; the rule below takes that name instead.
1049
1281
  (0, import_datalog4.rule)(
1050
- "stepsTo",
1282
+ "hop",
1051
1283
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
1052
1284
  [(0, import_datalog4.lit)("endsHolding", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))],
1053
1285
  "last write"
1054
1286
  ),
1287
+ // A name whose writes nothing orders leads to each of them, so a
1288
+ // caller that can use several values gets them all and one that needs
1289
+ // a single value gets none. A write stating no value stops every step.
1290
+ (0, import_datalog4.rule)(
1291
+ "hop",
1292
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP],
1293
+ [(0, import_datalog4.lit)("mayHold", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y")), (0, import_datalog4.lit)("writesAllStated", (0, import_datalog4.variable)("x"))],
1294
+ "one of several writes"
1295
+ ),
1055
1296
  // A fallback says the value is one of its branches, so each branch is
1056
1297
  // a step. A branch that resolves to nothing makes no claim, and two
1057
1298
  // branches resolving to different things fail the single-answer policy.
1058
1299
  (0, import_datalog4.rule)(
1059
- "stepsTo",
1300
+ "hop",
1060
1301
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"), VALUE_STEP],
1061
1302
  [(0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"))],
1062
1303
  "fallback"
1063
1304
  ),
1064
1305
  // An import steps to what the module exports under that name.
1065
1306
  (0, import_datalog4.rule)(
1066
- "stepsTo",
1307
+ "hop",
1067
1308
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("value"), VALUE_STEP],
1068
1309
  [
1069
1310
  (0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")),
@@ -1097,8 +1338,8 @@ var RESOLUTION_RULES = [
1097
1338
  // a method read off the result is the one the class declares. The
1098
1339
  // caveat below is about a factory function, and a class is not one.
1099
1340
  (0, import_datalog4.rule)(
1100
- "stepsTo",
1101
- [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
1341
+ "hop",
1342
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
1102
1343
  [
1103
1344
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
1104
1345
  (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("cls")),
@@ -1106,12 +1347,21 @@ var RESOLUTION_RULES = [
1106
1347
  ],
1107
1348
  "class instance"
1108
1349
  ),
1350
+ // The receiver a method is called on. Being one of a class is the
1351
+ // same hop a construction takes, so a method read off `self` finds
1352
+ // what the class declares.
1353
+ (0, import_datalog4.rule)(
1354
+ "hop",
1355
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
1356
+ [(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls"))],
1357
+ "receiver instance"
1358
+ ),
1109
1359
  // A finder the library declares, keyed on the base a pack named so a
1110
1360
  // project class with a method of the same name on another hierarchy is
1111
1361
  // left alone. The DESIGN says what a chain of them composes into.
1112
1362
  (0, import_datalog4.rule)(
1113
- "stepsTo",
1114
- [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
1363
+ "hop",
1364
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
1115
1365
  [
1116
1366
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
1117
1367
  (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
@@ -1128,8 +1378,8 @@ var RESOLUTION_RULES = [
1128
1378
  // instead of as the receiver. The argument having to reach the base a
1129
1379
  // pack named is what keeps an unrelated `get` out.
1130
1380
  (0, import_datalog4.rule)(
1131
- "stepsTo",
1132
- [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
1381
+ "hop",
1382
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
1133
1383
  [
1134
1384
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
1135
1385
  (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
@@ -1146,8 +1396,8 @@ var RESOLUTION_RULES = [
1146
1396
  // anything, keyed on the module it was imported from so a project
1147
1397
  // function spelled the same way is not mistaken for it.
1148
1398
  (0, import_datalog4.rule)(
1149
- "stepsTo",
1150
- [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), VALUE_STEP],
1399
+ "hop",
1400
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP],
1151
1401
  [
1152
1402
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
1153
1403
  (0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n")),
@@ -1157,10 +1407,24 @@ var RESOLUTION_RULES = [
1157
1407
  ],
1158
1408
  "declared import finder"
1159
1409
  ),
1410
+ // A block opened over a library's own constructor. The pack says
1411
+ // entering one gives back the object it built, so the name the block
1412
+ // opens is that call.
1413
+ (0, import_datalog4.rule)(
1414
+ "hop",
1415
+ [(0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("r"), VALUE_STEP],
1416
+ [
1417
+ (0, import_datalog4.lit)("entersAs", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("r")),
1418
+ (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
1419
+ (0, import_datalog4.lit)("comesFrom", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n")),
1420
+ (0, import_datalog4.lit)("entersAsSelf", (0, import_datalog4.variable)("mod"), (0, import_datalog4.variable)("n"))
1421
+ ],
1422
+ "context manager returns self"
1423
+ ),
1160
1424
  // Wrapper transparency, derived: calling a factory that returns a
1161
1425
  // function which calls its parameter k steps to argument k.
1162
1426
  (0, import_datalog4.rule)(
1163
- "stepsTo",
1427
+ "hop",
1164
1428
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
1165
1429
  [
1166
1430
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")),
@@ -1174,7 +1438,7 @@ var RESOLUTION_RULES = [
1174
1438
  // argument k. The callee has to come from the library the pack said,
1175
1439
  // so a local object spelled the same way is not mistaken for it.
1176
1440
  (0, import_datalog4.rule)(
1177
- "stepsTo",
1441
+ "hop",
1178
1442
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a"), VALUE_STEP],
1179
1443
  [
1180
1444
  (0, import_datalog4.lit)("calleeName", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n")),
@@ -1188,44 +1452,441 @@ var RESOLUTION_RULES = [
1188
1452
  // The one step that runs a function forwards: a call steps to what
1189
1453
  // the function it invokes returns.
1190
1454
  (0, import_datalog4.rule)(
1191
- "stepsTo",
1455
+ "hop",
1192
1456
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("ret"), RESULT_STEP],
1193
1457
  [(0, import_datalog4.lit)("invokes", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("ret"))],
1194
1458
  "call result"
1195
1459
  ),
1196
- // Where a walk gets to, and whether it ran a call on the way. The walk
1197
- // so far comes first, so demand stays on the value asked about; the
1198
- // README says what the other order cost.
1460
+ // What a function says it gives back when its body never states a
1461
+ // value. The adapter stays quiet about the annotation whenever the
1462
+ // body does state one, so the two never answer the same question.
1463
+ (0, import_datalog4.rule)(
1464
+ "hop",
1465
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"), RESULT_STEP],
1466
+ [
1467
+ (0, import_datalog4.lit)("invokes", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
1468
+ (0, import_datalog4.lit)("returnsClass", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("x")),
1469
+ (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls")),
1470
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls"))
1471
+ ],
1472
+ "declared return type"
1473
+ ),
1474
+ // Where a walk gets to, under the strongest step it took: value, then
1475
+ // instance, then result. The walk so far comes first, so demand stays
1476
+ // on the value asked about; the README says what the other order cost.
1199
1477
  (0, import_datalog4.rule)(
1200
1478
  "reaches",
1201
1479
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind")],
1202
1480
  [(0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))]
1203
1481
  ),
1482
+ // A rule per pair rather than one leaving the next step's kind free. A
1483
+ // free kind is a second question about the same relation, and a
1484
+ // demand-driven run then derives both to answer either.
1485
+ ...STEP_LATTICE.map(
1486
+ ({ soFar, next, took }) => (0, import_datalog4.rule)(
1487
+ "reaches",
1488
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), took],
1489
+ [
1490
+ (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), soFar),
1491
+ (0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), next)
1492
+ ]
1493
+ )
1494
+ ),
1495
+ // A context is an allocation site, or nothing at all for a value read
1496
+ // outside every site. Both are stated, so a rule that starts a walk
1497
+ // binds its context from a premise rather than from a negation.
1498
+ (0, import_datalog4.rule)("context", [NO_CONTEXT], [], "no context"),
1499
+ (0, import_datalog4.rule)(
1500
+ "context",
1501
+ [(0, import_datalog4.variable)("site")],
1502
+ [(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))],
1503
+ "site context"
1504
+ ),
1505
+ // The same closure, with the context the walk started under and the
1506
+ // context it arrived under. It takes `hop`, because an argument and a
1507
+ // property read have their own rules below.
1508
+ (0, import_datalog4.rule)(
1509
+ "reachesUnder",
1510
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("kind")],
1511
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("hop", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))],
1512
+ "under one hop"
1513
+ ),
1514
+ ...STEP_LATTICE.map(
1515
+ ({ soFar, next, took }) => (0, import_datalog4.rule)(
1516
+ "reachesUnder",
1517
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), took],
1518
+ [
1519
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), soFar),
1520
+ (0, import_datalog4.lit)("hop", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), next)
1521
+ ]
1522
+ )
1523
+ ),
1524
+ // The receiver read under a site is that site. The ordinary hop from a
1525
+ // receiver to its class stays in `hop`, so `self` under any context
1526
+ // still comes to the class a single-answer reader wants.
1204
1527
  (0, import_datalog4.rule)(
1205
- "reaches",
1206
- [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind")],
1528
+ "reachesUnder",
1529
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c"), VALUE_STEP],
1530
+ [(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("cls")), (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("cls"))],
1531
+ "receiver is the site"
1532
+ ),
1533
+ (0, import_datalog4.rule)(
1534
+ "reachesUnder",
1535
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")],
1207
1536
  [
1208
- (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), VALUE_STEP),
1209
- (0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("kind"))
1537
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
1538
+ (0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("cls")),
1539
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("cls"))
1540
+ ],
1541
+ "reached receiver is the site"
1542
+ ),
1543
+ // The object an expression refers to under a context. A site is an
1544
+ // answer here, unlike `objectOf`, and the class an instance is one of
1545
+ // is an answer only under no context.
1546
+ (0, import_datalog4.rule)(
1547
+ "objectOfUnder",
1548
+ [(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")],
1549
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))],
1550
+ "site is its own object"
1551
+ ),
1552
+ (0, import_datalog4.rule)(
1553
+ "objectOfUnder",
1554
+ [(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")],
1555
+ [
1556
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1557
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
1558
+ ],
1559
+ "name of a site"
1560
+ ),
1561
+ (0, import_datalog4.rule)(
1562
+ "objectOfUnder",
1563
+ [(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")],
1564
+ [
1565
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1566
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))
1567
+ ],
1568
+ "written object under a context"
1569
+ ),
1570
+ (0, import_datalog4.rule)(
1571
+ "objectOfUnder",
1572
+ [(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")],
1573
+ [
1574
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("c2"), RESULT_STEP),
1575
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))
1576
+ ],
1577
+ "returned object under a context"
1578
+ ),
1579
+ (0, import_datalog4.rule)(
1580
+ "objectOfUnder",
1581
+ [(0, import_datalog4.variable)("o"), NO_CONTEXT, (0, import_datalog4.variable)("cls")],
1582
+ [
1583
+ (0, import_datalog4.lit)(
1584
+ "reachesUnder",
1585
+ (0, import_datalog4.variable)("o"),
1586
+ NO_CONTEXT,
1587
+ (0, import_datalog4.variable)("cls"),
1588
+ NO_CONTEXT,
1589
+ INSTANCE_STEP
1590
+ ),
1591
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls"))
1592
+ ],
1593
+ "class reached with no context"
1594
+ ),
1595
+ (0, import_datalog4.rule)(
1596
+ "objectOfUnder",
1597
+ [(0, import_datalog4.variable)("o"), NO_CONTEXT, (0, import_datalog4.variable)("cls")],
1598
+ [(0, import_datalog4.lit)("instanceOf", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("cls"))],
1599
+ "receiver class with no context"
1600
+ ),
1601
+ (0, import_datalog4.rule)(
1602
+ "objectOfUnder",
1603
+ [(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o")],
1604
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("o"))],
1605
+ "object under a context is itself"
1606
+ ),
1607
+ // A property read goes on under the site the object was made at, so a
1608
+ // field read off two constructions gives each one its own value. A
1609
+ // class or a literal object keeps the context the walk was already in.
1610
+ (0, import_datalog4.rule)(
1611
+ "reachesUnder",
1612
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("site"), VALUE_STEP],
1613
+ [
1614
+ (0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
1615
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
1616
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("site")),
1617
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
1618
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
1619
+ ],
1620
+ "property read at a site"
1621
+ ),
1622
+ (0, import_datalog4.rule)(
1623
+ "reachesUnder",
1624
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("c"), VALUE_STEP],
1625
+ [
1626
+ (0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
1627
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
1628
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("obj")),
1629
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj")),
1630
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
1631
+ ],
1632
+ "property read off an object"
1633
+ ),
1634
+ (0, import_datalog4.rule)(
1635
+ "reachesUnder",
1636
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("kind")],
1637
+ [
1638
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
1639
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
1640
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("site")),
1641
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
1642
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
1643
+ ],
1644
+ "reached property read at a site"
1645
+ ),
1646
+ (0, import_datalog4.rule)(
1647
+ "reachesUnder",
1648
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("held"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")],
1649
+ [
1650
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
1651
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
1652
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("obj")),
1653
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj")),
1654
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
1655
+ ],
1656
+ "reached property read off an object"
1657
+ ),
1658
+ // A parameter goes on at the argument, under the context its caller
1659
+ // was read in, and only from the calls that run the function under the
1660
+ // context the walk is in. This is the one hop that changes context.
1661
+ (0, import_datalog4.rule)(
1662
+ "reachesUnder",
1663
+ [(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), VALUE_STEP],
1664
+ [
1665
+ (0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
1666
+ (0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("p")),
1667
+ (0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c3")),
1668
+ (0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("a"))
1669
+ ],
1670
+ "argument under a context"
1671
+ ),
1672
+ (0, import_datalog4.rule)(
1673
+ "reachesUnder",
1674
+ [(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), VALUE_STEP],
1675
+ [
1676
+ (0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
1677
+ (0, import_datalog4.lit)("paramNamed", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")),
1678
+ (0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c3")),
1679
+ (0, import_datalog4.lit)("callKeywordArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("a"))
1680
+ ],
1681
+ "keyword argument under a context"
1682
+ ),
1683
+ (0, import_datalog4.rule)(
1684
+ "reachesUnder",
1685
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), (0, import_datalog4.variable)("kind")],
1686
+ [
1687
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
1688
+ (0, import_datalog4.lit)("paramOf", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("p")),
1689
+ (0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c3")),
1690
+ (0, import_datalog4.lit)("callArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("i"), (0, import_datalog4.variable)("a"))
1691
+ ],
1692
+ "reached argument under a context"
1693
+ ),
1694
+ (0, import_datalog4.rule)(
1695
+ "reachesUnder",
1696
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("a"), (0, import_datalog4.variable)("c3"), (0, import_datalog4.variable)("kind")],
1697
+ [
1698
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("kind")),
1699
+ (0, import_datalog4.lit)("paramNamed", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("p")),
1700
+ (0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c2"), (0, import_datalog4.variable)("c3")),
1701
+ (0, import_datalog4.lit)("callKeywordArg", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("a"))
1702
+ ],
1703
+ "reached keyword argument under a context"
1704
+ ),
1705
+ // Which call runs which function under which context. A construction
1706
+ // runs its constructor under the site it makes, a method call runs
1707
+ // under the site its receiver is, and anything else under no context.
1708
+ (0, import_datalog4.rule)(
1709
+ "entersUnder",
1710
+ [(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("ctor"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller")],
1711
+ [
1712
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
1713
+ (0, import_datalog4.lit)("runsConstructor", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("ctor")),
1714
+ (0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller"))
1715
+ ],
1716
+ "construction enters its constructor"
1717
+ ),
1718
+ (0, import_datalog4.rule)(
1719
+ "entersUnder",
1720
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("caller")],
1721
+ [
1722
+ (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cal")),
1723
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("cal"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("m")),
1724
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("caller"), (0, import_datalog4.variable)("site")),
1725
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
1726
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
1727
+ (0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("caller"))
1728
+ ],
1729
+ "method call enters under its receiver"
1730
+ ),
1731
+ // A call written as a name runs with whatever receiver the body
1732
+ // around it has, so a plain function called from a method keeps the
1733
+ // site rather than taking every caller of it.
1734
+ (0, import_datalog4.rule)(
1735
+ "entersUnder",
1736
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c")],
1737
+ [
1738
+ (0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")),
1739
+ (0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
1740
+ (0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
1741
+ ],
1742
+ "named call enters under the site it is made in"
1743
+ ),
1744
+ (0, import_datalog4.rule)(
1745
+ "entersUnder",
1746
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"), NO_CONTEXT, (0, import_datalog4.variable)("caller")],
1747
+ [
1748
+ (0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")),
1749
+ (0, import_datalog4.lit)("callUnder", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("caller"))
1750
+ ],
1751
+ "call enters with no context"
1752
+ ),
1753
+ // The constructor a construction runs, the ancestry included, so a
1754
+ // subclass that declares none still fills in what it inherits.
1755
+ (0, import_datalog4.rule)(
1756
+ "runsConstructor",
1757
+ [(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")],
1758
+ [(0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f"))]
1759
+ ),
1760
+ (0, import_datalog4.rule)(
1761
+ "runsConstructor",
1762
+ [(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")],
1763
+ [
1764
+ (0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("b")),
1765
+ (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("base")),
1766
+ (0, import_datalog4.lit)("runsConstructor", (0, import_datalog4.variable)("base"), (0, import_datalog4.variable)("f"))
1210
1767
  ]
1211
1768
  ),
1212
- // Two rules rather than one leaving the next step's kind free. A free
1213
- // kind is a second question about the same relation, and a
1214
- // demand-driven run then derives both to answer either.
1769
+ // Which body a call is written in. One adapter states the call it
1770
+ // found and another states the callee, so both spellings are read.
1215
1771
  (0, import_datalog4.rule)(
1216
- "reaches",
1217
- [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP],
1772
+ "callInBody",
1773
+ [(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")],
1774
+ [(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
1775
+ ),
1776
+ (0, import_datalog4.rule)(
1777
+ "callInBody",
1778
+ [(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")],
1779
+ [(0, import_datalog4.lit)("bodyCallsDeep", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
1780
+ ),
1781
+ // The context a call is made under: every site of the class whose
1782
+ // method or constructor it is written in, and no context for a call
1783
+ // outside every method body.
1784
+ (0, import_datalog4.rule)(
1785
+ "callUnder",
1786
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("site")],
1787
+ [
1788
+ (0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
1789
+ (0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
1790
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
1791
+ ],
1792
+ "call in a method"
1793
+ ),
1794
+ (0, import_datalog4.rule)(
1795
+ "callUnder",
1796
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("site")],
1218
1797
  [
1219
- (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), RESULT_STEP),
1220
- (0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), VALUE_STEP)
1798
+ (0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
1799
+ (0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")),
1800
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
1801
+ ],
1802
+ "call in a constructor"
1803
+ ),
1804
+ // A plain function entered under a site makes its own calls under
1805
+ // that site, so a chain of plain functions off one method keeps it.
1806
+ (0, import_datalog4.rule)(
1807
+ "callUnder",
1808
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c")],
1809
+ [
1810
+ (0, import_datalog4.lit)("callOutsideMethod", (0, import_datalog4.variable)("r")),
1811
+ (0, import_datalog4.lit)("callInBody", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("r")),
1812
+ (0, import_datalog4.lit)("entersUnder", (0, import_datalog4.variable)("into"), (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("c4"))
1813
+ ],
1814
+ "call in a function entered under a site"
1815
+ ),
1816
+ (0, import_datalog4.rule)(
1817
+ "callUnder",
1818
+ [(0, import_datalog4.variable)("r"), NO_CONTEXT],
1819
+ [(0, import_datalog4.lit)("callOutsideMethod", (0, import_datalog4.variable)("r"))],
1820
+ "call outside every method"
1821
+ ),
1822
+ // The two questions a caller puts under a context, stopping where
1823
+ // `isWrittenAs` and `comesTo` stop, whatever context the walk ended in.
1824
+ (0, import_datalog4.rule)(
1825
+ "isWrittenAsUnder",
1826
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
1827
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("x"))]
1828
+ ),
1829
+ (0, import_datalog4.rule)(
1830
+ "isWrittenAsUnder",
1831
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
1832
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]
1833
+ ),
1834
+ (0, import_datalog4.rule)(
1835
+ "isWrittenAsUnder",
1836
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1837
+ [
1838
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1839
+ (0, import_datalog4.lit)("writtenValue", (0, import_datalog4.variable)("z"))
1221
1840
  ]
1222
1841
  ),
1223
1842
  (0, import_datalog4.rule)(
1224
- "reaches",
1225
- [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), RESULT_STEP],
1843
+ "isWrittenAsUnder",
1844
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1845
+ [
1846
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1847
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
1848
+ ]
1849
+ ),
1850
+ (0, import_datalog4.rule)(
1851
+ "comesToUnder",
1852
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
1853
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("x"))]
1854
+ ),
1855
+ (0, import_datalog4.rule)(
1856
+ "comesToUnder",
1857
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("x")],
1858
+ [(0, import_datalog4.lit)("context", (0, import_datalog4.variable)("c")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("x"))]
1859
+ ),
1860
+ (0, import_datalog4.rule)(
1861
+ "comesToUnder",
1862
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1863
+ [
1864
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1865
+ (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))
1866
+ ]
1867
+ ),
1868
+ (0, import_datalog4.rule)(
1869
+ "comesToUnder",
1870
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1871
+ [
1872
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), VALUE_STEP),
1873
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
1874
+ ]
1875
+ ),
1876
+ (0, import_datalog4.rule)(
1877
+ "comesToUnder",
1878
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1879
+ [
1880
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), INSTANCE_STEP),
1881
+ (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))
1882
+ ]
1883
+ ),
1884
+ (0, import_datalog4.rule)(
1885
+ "comesToUnder",
1886
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
1226
1887
  [
1227
- (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"), RESULT_STEP),
1228
- (0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("z"), RESULT_STEP)
1888
+ (0, import_datalog4.lit)("reachesUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"), (0, import_datalog4.variable)("c2"), INSTANCE_STEP),
1889
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
1229
1890
  ]
1230
1891
  ),
1231
1892
  // What a value comes down to: the walk that never ran a call, stopped
@@ -1243,6 +1904,18 @@ var RESOLUTION_RULES = [
1243
1904
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
1244
1905
  [(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), VALUE_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
1245
1906
  ),
1907
+ // An instance walk stops the same way, so a method read off
1908
+ // `new App()` still finds what the class declares.
1909
+ (0, import_datalog4.rule)(
1910
+ "comesTo",
1911
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
1912
+ [(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), INSTANCE_STEP), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
1913
+ ),
1914
+ (0, import_datalog4.rule)(
1915
+ "comesTo",
1916
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
1917
+ [(0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"), INSTANCE_STEP), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))]
1918
+ ),
1246
1919
  // The same stopping condition, for the walk that ran a call. A call
1247
1920
  // gets no `comesTo` answer on purpose: coming back with what a
1248
1921
  // factory returned would fight the unwrapping answer.
@@ -1283,6 +1956,13 @@ var RESOLUTION_RULES = [
1283
1956
  (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("ret"), (0, import_datalog4.variable)("z"))
1284
1957
  ]
1285
1958
  ),
1959
+ // Which expression running f hands back, whether f returns it, writes
1960
+ // it into a name first, or ends on it as a shorthand body.
1961
+ (0, import_datalog4.rule)(
1962
+ "returnsCall",
1963
+ [(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")],
1964
+ [(0, import_datalog4.lit)("returnsValue", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("v")), (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("v"), (0, import_datalog4.variable)("c"))]
1965
+ ),
1286
1966
  // What one call site put in a parameter, told apart from what the
1287
1967
  // other callers passed.
1288
1968
  (0, import_datalog4.rule)(
@@ -1380,18 +2060,34 @@ var RESOLUTION_RULES = [
1380
2060
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
1381
2061
  [(0, import_datalog4.lit)("givesBack", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")), (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))]
1382
2062
  ),
2063
+ // A construction is the object it made, and so is any name for it.
2064
+ // The class stays an answer too, so an instance whose site is not in
2065
+ // the run still reads what the class stores.
2066
+ (0, import_datalog4.rule)(
2067
+ "objectOf",
2068
+ [(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("site")],
2069
+ [(0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"))]
2070
+ ),
2071
+ (0, import_datalog4.rule)(
2072
+ "objectOf",
2073
+ [(0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("site")],
2074
+ [
2075
+ (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("site"), VALUE_STEP),
2076
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c"))
2077
+ ]
2078
+ ),
1383
2079
  // Which calls a function, found by the name the call is written as
1384
2080
  // rather than by resolving every callee in the project. A caller knows
1385
2081
  // the function and wants its call sites, so both of these start from
1386
2082
  // the function. Starting from `call` instead asks what every call in
1387
2083
  // the project imports, which was 72% of everything derived.
1388
2084
  (0, import_datalog4.rule)(
1389
- "callsFunction",
2085
+ "callsNamed",
1390
2086
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
1391
2087
  [(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))]
1392
2088
  ),
1393
2089
  (0, import_datalog4.rule)(
1394
- "callsFunction",
2090
+ "callsNamed",
1395
2091
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
1396
2092
  [
1397
2093
  (0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
@@ -1402,7 +2098,7 @@ var RESOLUTION_RULES = [
1402
2098
  // The same, for a language whose adapter writes the import down as a
1403
2099
  // declaration and the call's callee as the name referring to it.
1404
2100
  (0, import_datalog4.rule)(
1405
- "callsFunction",
2101
+ "callsNamed",
1406
2102
  [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
1407
2103
  [
1408
2104
  (0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
@@ -1411,6 +2107,62 @@ var RESOLUTION_RULES = [
1411
2107
  (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
1412
2108
  ]
1413
2109
  ),
2110
+ // `const f = (x) => ...` declares the name and puts the parameters on
2111
+ // the arrow, so everything above arrives at the declaration and
2112
+ // `paramOf` is about the arrow. One binds hop joins the two.
2113
+ (0, import_datalog4.rule)(
2114
+ "callsNamed",
2115
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
2116
+ [(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("g"))]
2117
+ ),
2118
+ // Every one of those, and the binds hop again over the whole
2119
+ // relation, so a property holding a name for a function is reached
2120
+ // the way it was before the two were told apart.
2121
+ (0, import_datalog4.rule)("callsFunction", [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")], [(0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f"))]),
2122
+ (0, import_datalog4.rule)(
2123
+ "callsFunction",
2124
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
2125
+ [(0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("g"), (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("callsFunction", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("g"))]
2126
+ ),
2127
+ // A function written on an object, called off it: `client.get(o)`.
2128
+ // The receiver comes from the object through `refersToObject`, not from
2129
+ // `objectOf`: a walk from every reader of the name was most of a run.
2130
+ (0, import_datalog4.rule)(
2131
+ "callsFunction",
2132
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("f")],
2133
+ [
2134
+ (0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("f")),
2135
+ (0, import_datalog4.lit)("refersToObject", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("obj")),
2136
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
2137
+ (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("c"))
2138
+ ]
2139
+ ),
2140
+ // The expressions that refer to an object literal by binding alone: the
2141
+ // declaration written as it, a reference or import of that, and a
2142
+ // fallback over any of those. Asked from the object, so it visits only them.
2143
+ (0, import_datalog4.rule)("refersToObject", [(0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("obj")], [(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("obj"))]),
2144
+ (0, import_datalog4.rule)(
2145
+ "refersToObject",
2146
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
2147
+ [(0, import_datalog4.lit)("refersToObject", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("obj")), (0, import_datalog4.lit)("binds", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("y"))]
2148
+ ),
2149
+ (0, import_datalog4.rule)(
2150
+ "refersToObject",
2151
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
2152
+ [
2153
+ (0, import_datalog4.lit)("refersToObject", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("obj")),
2154
+ (0, import_datalog4.lit)("moduleExport", (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("y")),
2155
+ (0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
2156
+ ]
2157
+ ),
2158
+ (0, import_datalog4.rule)(
2159
+ "refersToObject",
2160
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("obj")],
2161
+ [
2162
+ (0, import_datalog4.lit)("refersToObject", (0, import_datalog4.variable)("b"), (0, import_datalog4.variable)("obj")),
2163
+ (0, import_datalog4.lit)("fallbackBranch", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("b"))
2164
+ ]
2165
+ ),
1414
2166
  // What an object contains, its base class included, so a method the base
1415
2167
  // declares is found on a subclass that never overrode it. A method both
1416
2168
  // declare gives two, and the caller decides. This is its own relation
@@ -1428,7 +2180,8 @@ var RESOLUTION_RULES = [
1428
2180
  (0, import_datalog4.lit)("extends", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("base")),
1429
2181
  (0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("base"), (0, import_datalog4.variable)("baseCls")),
1430
2182
  (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("baseCls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
1431
- ]
2183
+ ],
2184
+ BASE_CLASS_RULE
1432
2185
  ),
1433
2186
  // An association is read off an instance as a property, and stating
1434
2187
  // it as `contains` is what puts it on the ancestry rule, so a concern
@@ -1452,6 +2205,69 @@ var RESOLUTION_RULES = [
1452
2205
  ],
1453
2206
  "constructed association"
1454
2207
  ),
2208
+ // What the constructor put on the receiver. The class is the object
2209
+ // for an instance whose own site is not in the run.
2210
+ (0, import_datalog4.rule)(
2211
+ "contains",
2212
+ [(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
2213
+ [
2214
+ (0, import_datalog4.lit)("initializes", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("f")),
2215
+ (0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
2216
+ ],
2217
+ "constructor store"
2218
+ ),
2219
+ // What any other method of the class put there. Two methods writing
2220
+ // one name give two rows, since nothing here orders them.
2221
+ (0, import_datalog4.rule)(
2222
+ "contains",
2223
+ [(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
2224
+ [
2225
+ (0, import_datalog4.lit)("holdsProperty", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("f")),
2226
+ (0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
2227
+ ],
2228
+ "method store"
2229
+ ),
2230
+ // A write through a name rather than through the receiver,
2231
+ // `client.timeout = 5`, which lands on whatever that name refers to.
2232
+ (0, import_datalog4.rule)(
2233
+ "contains",
2234
+ [(0, import_datalog4.variable)("obj"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
2235
+ [
2236
+ (0, import_datalog4.lit)("storesProperty", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")),
2237
+ (0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("obj"))
2238
+ ],
2239
+ "named receiver store"
2240
+ ),
2241
+ // A call written with a class's own name, which is how most languages
2242
+ // spell a construction. A language that spells one some other way
2243
+ // states its own rule for this, the way Ruby does for `Const.new`.
2244
+ (0, import_datalog4.rule)(
2245
+ "constructsNamed",
2246
+ [(0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls")],
2247
+ [(0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("cls")), (0, import_datalog4.lit)("callsNamed", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("cls"))]
2248
+ ),
2249
+ // Each construction is an object of its own containing what its
2250
+ // class stores, so two sites are two objects.
2251
+ (0, import_datalog4.rule)(
2252
+ "contains",
2253
+ [(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held")],
2254
+ [
2255
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
2256
+ (0, import_datalog4.lit)("contains", (0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("n"), (0, import_datalog4.variable)("held"))
2257
+ ],
2258
+ "allocated instance"
2259
+ ),
2260
+ // A call that makes one of a class. Every finder a pack declared is
2261
+ // one too, so `User.find(1)` is a site the same way `User.new` is.
2262
+ (0, import_datalog4.rule)(
2263
+ "allocates",
2264
+ [(0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")],
2265
+ [
2266
+ (0, import_datalog4.lit)("call", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("c")),
2267
+ (0, import_datalog4.lit)("stepsTo", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"), INSTANCE_STEP)
2268
+ ],
2269
+ "allocation site"
2270
+ ),
1455
2271
  // The library base a class's ancestry arrives at, however many of a
1456
2272
  // project's own classes sit in between. A base the run declares has a
1457
2273
  // node to keep walking from; one it does not has only a name.
@@ -1541,8 +2357,8 @@ var RESOLUTION_RULES = [
1541
2357
  ]
1542
2358
  ),
1543
2359
  // Where a name comes from, when what it refers to lives outside the
1544
- // source being read. A walk ends at something written out in source,
1545
- // so it never reaches a library's own function.
2360
+ // source being read. A walk ends at what the source writes out, so it
2361
+ // never reaches a library's own function; these rules do.
1546
2362
  (0, import_datalog4.rule)(
1547
2363
  "comesFrom",
1548
2364
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
@@ -1556,6 +2372,28 @@ var RESOLUTION_RULES = [
1556
2372
  (0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("y"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n"))
1557
2373
  ]
1558
2374
  ),
2375
+ // A member read off a whole-module import: the member's own name is
2376
+ // what the module exports, so `fastapi.APIRouter` comes from
2377
+ // fastapi's `APIRouter`. Directly, or through a name for the module.
2378
+ (0, import_datalog4.rule)(
2379
+ "comesFrom",
2380
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
2381
+ [
2382
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("n")),
2383
+ (0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT)
2384
+ ],
2385
+ NAMESPACE_MEMBER_RULE
2386
+ ),
2387
+ (0, import_datalog4.rule)(
2388
+ "comesFrom",
2389
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
2390
+ [
2391
+ (0, import_datalog4.lit)("readsProperty", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("n")),
2392
+ (0, import_datalog4.lit)("reaches", (0, import_datalog4.variable)("o"), (0, import_datalog4.variable)("ns"), VALUE_STEP),
2393
+ (0, import_datalog4.lit)("imports", (0, import_datalog4.variable)("ns"), (0, import_datalog4.variable)("m"), NAMESPACE_IMPORT)
2394
+ ],
2395
+ NAMESPACE_MEMBER_RULE
2396
+ ),
1559
2397
  // Calling f ends up calling the name n that module m exports, one
1560
2398
  // hop through f's own body or deeper through a wrapper of a wrapper.
1561
2399
  // Several results is normal: a composed decorator applies them all.
@@ -1585,6 +2423,13 @@ var RESOLUTION_RULES = [
1585
2423
  [(0, import_datalog4.lit)("comesTo", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")), (0, import_datalog4.lit)("func", (0, import_datalog4.variable)("z"))]
1586
2424
  )
1587
2425
  ];
2426
+ function alsoSteps(rules) {
2427
+ return [
2428
+ ...rules,
2429
+ ...rules.filter((r) => r.head.relation === "hop").map((r) => ({ ...r, head: { ...r.head, relation: "stepsTo" } }))
2430
+ ];
2431
+ }
2432
+ var RESOLUTION_RULES = alsoSteps(STATED_RULES);
1588
2433
  var RESOLUTION_QUESTIONS = [
1589
2434
  (0, import_datalog4.rule)(
1590
2435
  "wantedResolves",
@@ -1607,12 +2452,55 @@ var RESOLUTION_QUESTIONS = [
1607
2452
  [(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("isWrittenAs", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
1608
2453
  ),
1609
2454
  // A call is given no `comesTo`, so this is the only way to ask what
1610
- // object one arrives at, and without it a demand-driven run derives
1611
- // `objectOf` nowhere.
2455
+ // object one arrives at, and a demand-driven run derives `objectOf`
2456
+ // nowhere without it. An allocation site is not one of the answers.
1612
2457
  (0, import_datalog4.rule)(
1613
2458
  "wantedObjectOf",
1614
2459
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")],
1615
- [(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")), (0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z"))]
2460
+ [
2461
+ (0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("x")),
2462
+ (0, import_datalog4.lit)("objectOf", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("z")),
2463
+ (0, import_datalog4.lit)("objectValue", (0, import_datalog4.variable)("z"))
2464
+ ]
2465
+ ),
2466
+ // The same three questions under one allocation site, keyed by the
2467
+ // value and the site both. An allocation site is an answer here,
2468
+ // unlike `wantedObjectOf`, since a site is what a context is.
2469
+ (0, import_datalog4.rule)(
2470
+ "wantedIsWrittenAsUnder",
2471
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
2472
+ [
2473
+ (0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
2474
+ (0, import_datalog4.lit)("isWrittenAsUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
2475
+ ]
2476
+ ),
2477
+ // Where a class was made, for a caller about to ask a value question
2478
+ // under each. Going through `constructsNamed` keeps the demand on the
2479
+ // calls written with the class's name rather than on every call.
2480
+ (0, import_datalog4.rule)(
2481
+ "wantedAllocatedAt",
2482
+ [(0, import_datalog4.variable)("cls"), (0, import_datalog4.variable)("site")],
2483
+ [
2484
+ (0, import_datalog4.lit)("wantedSites", (0, import_datalog4.variable)("cls")),
2485
+ (0, import_datalog4.lit)("constructsNamed", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls")),
2486
+ (0, import_datalog4.lit)("allocates", (0, import_datalog4.variable)("site"), (0, import_datalog4.variable)("cls"))
2487
+ ]
2488
+ ),
2489
+ (0, import_datalog4.rule)(
2490
+ "wantedComesToUnder",
2491
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
2492
+ [
2493
+ (0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
2494
+ (0, import_datalog4.lit)("comesToUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
2495
+ ]
2496
+ ),
2497
+ (0, import_datalog4.rule)(
2498
+ "wantedObjectOfUnder",
2499
+ [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z")],
2500
+ [
2501
+ (0, import_datalog4.lit)("wantedUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c")),
2502
+ (0, import_datalog4.lit)("objectOfUnder", (0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("c"), (0, import_datalog4.variable)("z"))
2503
+ ]
1616
2504
  ),
1617
2505
  // The same for the function a call returns: `app.use(requireCaller(config))`
1618
2506
  // registers what the factory gives back, and `resolves` on the call
@@ -1629,6 +2517,19 @@ var RESOLUTION_QUESTIONS = [
1629
2517
  [(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("z")],
1630
2518
  [(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("p")), (0, import_datalog4.lit)("paramAt", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("z"))]
1631
2519
  ),
2520
+ // The argument as the caller wrote it. A parameter given a GraphQL
2521
+ // document has no `paramAt` answer, since that settles through
2522
+ // `comesTo`, which stops at a function or an object.
2523
+ (0, import_datalog4.rule)(
2524
+ "wantedPassesArgument",
2525
+ [(0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("a")],
2526
+ [(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("p")), (0, import_datalog4.lit)("passesArgument", (0, import_datalog4.variable)("r"), (0, import_datalog4.variable)("p"), (0, import_datalog4.variable)("a"))]
2527
+ ),
2528
+ (0, import_datalog4.rule)(
2529
+ "wantedReturnsCall",
2530
+ [(0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c")],
2531
+ [(0, import_datalog4.lit)("wanted", (0, import_datalog4.variable)("f")), (0, import_datalog4.lit)("returnsCall", (0, import_datalog4.variable)("f"), (0, import_datalog4.variable)("c"))]
2532
+ ),
1632
2533
  (0, import_datalog4.rule)(
1633
2534
  "wantedComesFrom",
1634
2535
  [(0, import_datalog4.variable)("x"), (0, import_datalog4.variable)("m"), (0, import_datalog4.variable)("n")],
@@ -1892,36 +2793,62 @@ var RESOLUTION_QUESTIONS = [
1892
2793
  var ANSWER_RELATIONS = [
1893
2794
  ...new Set(RESOLUTION_QUESTIONS.map((r) => r.head.relation))
1894
2795
  ];
2796
+ var UNDER_ANSWER_RELATIONS = [
2797
+ "wantedIsWrittenAsUnder",
2798
+ "wantedComesToUnder",
2799
+ "wantedObjectOfUnder"
2800
+ ];
1895
2801
  // Annotate the CommonJS export names for ESM import in node:
1896
2802
  0 && (module.exports = {
1897
2803
  ANSWER_RELATIONS,
1898
2804
  ASKING_RELATIONS,
2805
+ BASE_CLASS_RULE,
1899
2806
  FACT_CONTRACT_CASES,
2807
+ INSTANCE_STEP,
1900
2808
  NAMESPACE_IMPORT,
1901
2809
  NAMESPACE_IMPORT_NAME,
2810
+ NAMESPACE_MEMBER_RULE,
2811
+ NO_CONTEXT,
2812
+ NO_CONTEXT_NAME,
1902
2813
  RESOLUTION_QUESTIONS,
1903
2814
  RESOLUTION_RULES,
1904
2815
  RESULT_STEP,
2816
+ UNDER_ANSWER_RELATIONS,
2817
+ UNDER_QUESTION_ROW_BUDGET,
2818
+ UNDER_RUN_ROW_BUDGET,
1905
2819
  VALUE_STEP,
2820
+ addPackWords,
1906
2821
  agreedMountPrefix,
2822
+ allocationSitesOf,
2823
+ alsoSteps,
2824
+ answersByKey,
1907
2825
  askResolution,
2826
+ askResolutionUnder,
1908
2827
  calleeOutcomeOf,
1909
2828
  calleeOutcomes,
1910
2829
  checkFactContract,
2830
+ comesToUnder,
1911
2831
  couldBeSettled,
1912
2832
  explainResolutionProof,
1913
2833
  explainResolvedKey,
2834
+ isWrittenAsUnder,
1914
2835
  joinMountedPath,
1915
2836
  mountPathsOf,
1916
2837
  nodeOfKey,
2838
+ objectOfUnder,
1917
2839
  placeholderValues,
1918
2840
  queryFacts,
1919
2841
  renderExplanation,
1920
2842
  resolutionProgram,
2843
+ resolutionUnderProgram,
1921
2844
  singleAnswers,
1922
2845
  startsAtName,
2846
+ underQuestionSpend,
1923
2847
  valueLeftByWrites,
1924
2848
  writesRunInOrder,
1925
2849
  writtenSourcesOf,
1926
- writtenValueOf
2850
+ writtenValueOf,
2851
+ writtenValueUnder,
2852
+ writtenValuesByKey,
2853
+ writtenValuesOf
1927
2854
  });