diff --git a/docs/assertions-module/4-imp.html b/docs/assertions-module/4-imp.html
index 4a7e1c308..f7defe4dd 100644
--- a/docs/assertions-module/4-imp.html
+++ b/docs/assertions-module/4-imp.html
@@ -85,10 +85,9 @@ description only, whereas B could be any subtree of an assertion.
typedefstructimplication {
-structpcalc_prop *if_spec; which objects are affected
+structpcalc_prop *if_proposition; which objects are affectedstructparse_node *then_pn; what assertion is implied about themintimplied_likelihood; with what certainty level
-structimplication *next_implication; in list of implicationsCLASS_DEFINITION} implication;
@@ -143,15 +142,13 @@ is to store them and sit on them.
Check that the conclusion involves only a single either/or property3.2.3;implication *imp = CREATE(implication);
-imp->if_spec = premiss;
+imp->if_proposition = premiss;imp->then_pn = py;imp->implied_likelihood = prevailing_mood;
-
-imp->next_implication = InferenceSubjects::get_implications(premiss_kind);
-InferenceSubjects::set_implications(premiss_kind, imp);
+ADD_TO_LINKED_LIST(imp, implication, InferenceSubjects::get_implications(premiss_kind));LOGIF(IMPLICATIONS, "Forming implication for $j: $D implies\n $T",
-premiss_kind, imp->if_spec, imp->then_pn);
+premiss_kind, imp->if_proposition, imp->then_pn);
§3.2.1. Find the premiss kind and specification3.2.1 =
@@ -259,9 +256,9 @@ basis of the inferences so far drawn about it.
if (k) Assertions::Implications::set_possessed_flags(k);inference *inf;
-KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
-property *prn = World::Inferences::get_property(inf);
-if ((Properties::is_either_or(prn)) && (World::Inferences::get_certainty(inf) != UNKNOWN_CE))
+KNOWLEDGE_LOOP(inf, infs, property_inf) {
+property *prn = PropertyInferences::get_property(inf);
+if ((Properties::is_either_or(prn)) && (Inferences::get_certainty(inf) != UNKNOWN_CE))See what we can get out of this inference5.1; }}
@@ -275,7 +272,7 @@ of not being open, and vice versa.
-inttruth_state = TRUE, certainty = World::Inferences::get_certainty(inf);
+inttruth_state = TRUE, certainty = Inferences::get_certainty(inf);if (certainty < 0) { certainty = -certainty; truth_state = FALSE; }possession_marker *pom = Properties::get_possession_marker(prn);
@@ -316,12 +313,12 @@ no better a certainty level.
inference_subject *k = InferenceSubjects::narrowest_broader_subject(domain);if ((k) && (Assertions::Implications::check_implications_of(k, candidate))) returnTRUE;
-if (InferenceSubjects::get_implications(domain))
+if (LinkedLists::len(InferenceSubjects::get_implications(domain)) > 0)LOGIF(IMPLICATIONS, "Considering implications about $j as they apply to $j:\n",domain, candidate);implication *imp;
-for (imp = InferenceSubjects::get_implications(domain); imp; imp = imp->next_implication)
+LOOP_OVER_LINKED_LIST(imp, implication, InferenceSubjects::get_implications(domain))Consider this individual implication as it applies to the candidate6.1;returnFALSE;
@@ -337,7 +334,7 @@ no better a certainty level.
if (imp->implied_likelihood < 0) conclusion_state = (conclusion_state)?FALSE:TRUE;LOGIF(IMPLICATIONS, "$D => $T (certainty %d; changed state %d)\n",
-imp->if_spec, imp->then_pn, imp->implied_likelihood, conclusion_state);
+imp->if_proposition, imp->then_pn, imp->implied_likelihood, conclusion_state);property *conclusion_prop = AdjectiveAmbiguity::has_either_or_property_meaning(AdjectivalPredicates::to_adjective(pred), NULL);
@@ -346,7 +343,7 @@ no better a certainty level.
possession_marker *pom = Properties::get_possession_marker(conclusion_prop);Check that the conclusion is not redundant or irrelevant6.1.2;
-intcandidate_qualifies = Assert::test_at_compile_time(imp->if_spec, candidate);
+intcandidate_qualifies = Assert::test_at_compile_time(imp->if_proposition, candidate);if (candidate_qualifies) {LOGIF(IMPLICATIONS, "PASS: changing property $Y of $j\n", conclusion_prop, candidate);
diff --git a/docs/assertions-module/6-er.html b/docs/assertions-module/6-er.html
index 9ff32e048..a22103186 100644
--- a/docs/assertions-module/6-er.html
+++ b/docs/assertions-module/6-er.html
@@ -254,14 +254,14 @@ to behave as if \(B(y, x)\) had also been asserted whenever \(B(x, y)\) has, if
Reject non-assertable relations7.1;if (Relations::Explicit::stored_dynamically(bp)) {
-World::Inferences::draw_relation_spec(bp, spec0, spec1);
+Inferences::draw_relation_spec(bp, spec0, spec1);returnTRUE; } else {if ((infs0 == NULL) || (infs1 == NULL)) Reject relationship with nothing7.2;if (Relations::Explicit::allow_arbitrary_assertions(bp)) {
-World::Inferences::draw_relation(bp, infs0, infs1);
+Inferences::draw_relation(bp, infs0, infs1);if ((Relations::Explicit::get_form_of_relation(bp) == Relation_Sym_VtoV) && (infs0 != infs1))
-World::Inferences::draw_relation(bp, infs1, infs0);
+Inferences::draw_relation(bp, infs1, infs0);returnTRUE; }if (Relations::Explicit::is_explicit_with_runtime_storage(bp)) {
@@ -321,7 +321,7 @@ inferences for \(y\) and \(z\).
inference_subject *swap=infs0; infs0=infs1; infs1=swap; }property *prn = Relations::Explicit::get_i6_storage_property(bp);
-World::Inferences::draw_property(infs0, prn, InferenceSubjects::as_constant(infs1));
+PropertyInferences::draw(infs0, prn, InferenceSubjects::as_constant(infs1));}
§9. We need do nothing special: these relations can be compiled from their schemas.
diff --git a/docs/assertions-module/6-terr.html b/docs/assertions-module/6-terr.html
index 69e685576..0efe2a70c 100644
--- a/docs/assertions-module/6-terr.html
+++ b/docs/assertions-module/6-terr.html
@@ -212,7 +212,7 @@ setting a global variable.
"a variable can only be given its value straightforwardly or ""qualified by 'usually'","not with 'always', 'seldom' or 'never'.");
-elseWorld::Inferences::draw_property(
+elsePropertyInferences::draw(NonlocalVariables::to_subject(q), P_variable_initial_value, spec1);returnTRUE; }
diff --git a/docs/core-module/1-cp.html b/docs/core-module/1-cp.html
index ef3a1f2cd..4431ca684 100644
--- a/docs/core-module/1-cp.html
+++ b/docs/core-module/1-cp.html
@@ -159,12 +159,14 @@ We begin with core itself.
enumcomparative_bp_data_CLASSenumcounting_data_CLASSenuminference_CLASS
+enuminference_family_CLASSenuminference_subject_CLASSenuminference_subject_family_CLASSenummeasurement_definition_CLASSenumnamed_rulebook_outcome_CLASSenumplacement_affecting_CLASSenumproperty_CLASS
+enumproperty_inference_data_CLASSenumproperty_permission_CLASSenumproperty_of_value_storage_CLASSenumproperty_setting_bp_data_CLASS
@@ -185,6 +187,7 @@ We begin with core itself.
DECLARE_CLASS(comparative_bp_data)DECLARE_CLASS(counting_data)DECLARE_CLASS(inference)
+DECLARE_CLASS(inference_family)DECLARE_CLASS(inference_subject)DECLARE_CLASS(inference_subject_family)DECLARE_CLASS(measurement_definition)
@@ -193,6 +196,7 @@ We begin with core itself.
DECLARE_CLASS(property_of_value_storage)DECLARE_CLASS(property_permission)DECLARE_CLASS(property)
+DECLARE_CLASS(property_inference_data)DECLARE_CLASS(property_setting_bp_data)DECLARE_CLASS(rule)DECLARE_CLASS(rulebook)
diff --git a/docs/core-module/1-htc.html b/docs/core-module/1-htc.html
index 871994745..6b8daa0d7 100644
--- a/docs/core-module/1-htc.html
+++ b/docs/core-module/1-htc.html
@@ -245,7 +245,8 @@ so on. Those absolute basics are made here.
BENCH(NounIdentifiers::name_all)BENCH(OrderingInstances::objects_in_definition_sequence)Task::advance_stage_to(MODEL_COMPLETE_CSEQ, I"Completing the model world", -1);
-BENCH(World::complete)
+BENCH(World::stages_II_and_III)
+BENCH(World::stage_IV)
§2.6. Tables and grammar2.6 =
@@ -262,7 +263,7 @@ so on. Those absolute basics are made here.
BENCH(Tables::check_tables_for_kind_clashes)BENCH(RTTables::compile_print_table_names)BENCH(PL::Parsing::traverse)
-BENCH(World::complete_additions)
+BENCH(World::stage_V)
§2.7. Phrases and rules2.7 =
@@ -303,7 +304,8 @@ so on. Those absolute basics are made here.
BENCH(RTRelations::compile_defined_relation_constants)BENCH(RTKinds::compile_data_type_support_routines)BENCH(RTKinds::I7_Kind_Name_routine)
-BENCH(World::Compile::compile)
+BENCH(Plugins::Call::compile_model_tables)
+BENCH(InferenceSubjects::emit_all)BENCH_IF(backdrops_plugin, PL::Backdrops::write_found_in_routines)BENCH_IF(map_plugin, PL::Map::write_door_dir_routines)BENCH_IF(map_plugin, PL::Map::write_door_to_routines)
diff --git a/docs/core-module/2-si.html b/docs/core-module/2-si.html
index a9f885fce..60757a8ae 100644
--- a/docs/core-module/2-si.html
+++ b/docs/core-module/2-si.html
@@ -310,10 +310,10 @@ making no sense.
char *message, char *explanation) {ACT_ON_SIGILProblems::quote_subject(1, infs);
-Problems::quote_source(2, World::Inferences::where_inferred(inf));
+Problems::quote_source(2, Inferences::where_inferred(inf));Problems::quote_text(3, message);Problems::quote_text(4, explanation);
-Problems::quote_property(5, World::Inferences::get_property(inf));
+Problems::quote_property(5, PropertyInferences::get_property(inf));Problems::issue_problem_begin(Task::syntax_tree(), explanation);Problems::issue_problem_segment("You wrote %2: but the property %5 for the %1 %3%S.%L, %4");
diff --git a/docs/if-module/3-bck.html b/docs/if-module/3-bck.html
index 773278ce3..eb8fe2cb1 100644
--- a/docs/if-module/3-bck.html
+++ b/docs/if-module/3-bck.html
@@ -82,10 +82,10 @@ inside something generates FO
inferences to avoid piling up bogus inconsistencies.
-
defineFOUND_IN_INF56 for backdrop things in many places
-defineFOUND_EVERYWHERE_INF57 ditto
-
+inference_family *FOUND_IN_INF = NULL; 56; for backdrop things in many places
+inference_family *FOUND_EVERYWHERE_INF = NULL; 57; ditto
+
kind *K_backdrop = NULL;property *P_scenery = NULL; an I7 either/or property marking something as sceneryproperty *P_absent = NULL; an I6-only property for backdrops out of play
@@ -105,6 +105,10 @@ inferences to avoid piling up bogus inconsistencies.
§4. Kinds. This a kind name to do with backdrops which Inform provides special support
for; it recognises the English name when defined by the Standard Rules. (So
@@ -162,7 +170,7 @@ Standard Rules. (So there is no need to translate this to other languages.)
}intPL::Backdrops::object_is_scenery(instance *I) {
-if (World::Inferences::get_EO_state(Instances::as_subject(I), P_scenery) > 0)
+if (Inferences::get_EO_state(Instances::as_subject(I), P_scenery) > 0)returnTRUE;returnFALSE;}
@@ -180,10 +188,6 @@ Standard Rules. (So there is no need to translate this to other languages.)
§13. Since backdrops are contained using different mechanisms, the following
(which does nothing if Backdrops isn't plugged in) adds backdrop contents to
@@ -327,7 +331,7 @@ been asserted true:
"is a vehicle which is everywhere.' is not.");return; }
-World::Inferences::draw(FOUND_EVERYWHERE_INF,
+Inferences::draw(FOUND_EVERYWHERE_INF,Instances::as_subject(I), prevailing_mood, NULL, NULL);}
§16.3. Anything in or part of a region is necessarily a room, if it isn't known
@@ -385,7 +385,7 @@ to be a region already:
inference_subject *rm = Instances::as_subject(I1);parse_node *spec = Rvalues::from_instance(I0);Propositions::Abstract::assert_kind_of_instance(I1, K_room);
-World::Inferences::draw_property(rm, P_map_region, spec);
+PropertyInferences::draw(rm, P_map_region, spec);
§17. Note that because we use regular PARENTAGE_INF inferences to remember
@@ -406,8 +406,8 @@ region is either the next broadest region containing it, or else intPL::Regions::regions_complete_model(intstage) {
-if (stage == 2) Assert map-region properties of rooms and regions18.1;
-if (stage == 3) Assert regional-found-in properties of regions18.2;
+if (stage == WORLD_STAGE_II) Assert map-region properties of rooms and regions18.1;
+if (stage == WORLD_STAGE_III) Assert regional-found-in properties of regions18.2;returnFALSE;}
@@ -427,7 +427,7 @@ region is either the next broadest region containing it, or else if ((Instances::of_kind(I, K_room)) || (Instances::of_kind(I, K_region))) {parse_node *where = NULL;
-parse_node *val = World::Inferences::get_prop_state_at(
+parse_node *val = Inferences::get_prop_state_at(Instances::as_subject(I), P_map_region, &where);if (val) {instance *reg =
diff --git a/docs/if-module/3-sm.html b/docs/if-module/3-sm.html
index c473e6cc1..3abeb0830 100644
--- a/docs/if-module/3-sm.html
+++ b/docs/if-module/3-sm.html
@@ -126,12 +126,13 @@ carries, wears, supports or incorporates it.
indications of spatial structure:
-
defineIS_ROOM_INF50 is O a room?
-defineCONTAINS_THINGS_INF51 does O contain things?
-definePARENTAGE_INF52 where is O located?
-definePARENTAGE_HERE_INF53 located vaguely as "here"?
-definePARENTAGE_NOWHERE_INF54 located vaguely as "nowhere"?
-definePART_OF_INF55 is O a part of another object?
+
+inference_family *IS_ROOM_INF = NULL; 50 is O a room?
+inference_family *CONTAINS_THINGS_INF = NULL; 51 does O contain things?
+inference_family *PARENTAGE_INF = NULL; 52 where is O located?
+inference_family *PARENTAGE_HERE_INF = NULL; 53 located vaguely as "here"?
+inference_family *PARENTAGE_NOWHERE_INF = NULL; 54 located vaguely as "nowhere"?
+inference_family *PART_OF_INF = NULL; 55 is O a part of another object?
§4. The Spatial plugin also needs to know about a considerable number of special
kinds and properties:
@@ -174,6 +175,16 @@ timing issue to get around (see below).
voidPL::Spatial::start(void) {
+IS_ROOM_INF = Inferences::new_family(I"IS_ROOM_INF", CI_DIFFER_IN_INFS1);
+METHOD_ADD(IS_ROOM_INF, EXPLAIN_CONTRADICTION_INF_MTID, PL::Spatial::is_room_explain_contradiction);
+CONTAINS_THINGS_INF = Inferences::new_family(I"CONTAINS_THINGS_INF", CI_DIFFER_IN_INFS1);
+PARENTAGE_INF = Inferences::new_family(I"PARENTAGE_INF", CI_DIFFER_IN_INFS1);
+METHOD_ADD(PARENTAGE_INF, EXPLAIN_CONTRADICTION_INF_MTID, PL::Spatial::parentage_explain_contradiction);
+PARENTAGE_HERE_INF = Inferences::new_family(I"PARENTAGE_HERE_INF", CI_DIFFER_IN_INFS1);
+PARENTAGE_NOWHERE_INF = Inferences::new_family(I"PARENTAGE_NOWHERE_INF", CI_DIFFER_IN_INFS1);
+PART_OF_INF = Inferences::new_family(I"PART_OF_INF", CI_DIFFER_IN_INFS1);
+
+PLUGIN_REGISTER(PLUGIN_CREATE_INFERENCE_FAMILIES, PL::Spatial::create_inference_families);PLUGIN_REGISTER(PLUGIN_CREATE_INFERENCES, PL::Spatial::create_inference_subjects);PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL::Spatial::spatial_new_base_kind_notify);PLUGIN_REGISTER(PLUGIN_ACT_ON_SPECIAL_NPS, PL::Spatial::spatial_act_on_special_NPs);
@@ -191,6 +202,43 @@ timing issue to get around (see below).
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, PL::Spatial::spatial_add_to_World_index);PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, PL::Spatial::spatial_intervene_in_assertion);}
+
+intPL::Spatial::is_room_explain_contradiction(inference_family *f, inference *A,
+inference *B, intsimilarity, inference_subject *subj) {
+StandardProblems::two_sentences_problem(_p_(PM_WhenIsARoomNotARoom),
+A->inferred_from,
+"this looks like a contradiction",
+"because apparently something would have to be both a room and not a "
+"room at the same time.");
+returnTRUE;
+}
+
+intPL::Spatial::parentage_explain_contradiction(inference_family *f, inference *A,
+inference *B, intsimilarity, inference_subject *subj) {
+if (Inferences::get_reference_as_object(A) != Inferences::get_reference_as_object(B)) {
+Problems::quote_source(1, Inferences::where_inferred(A));
+Problems::quote_source(2, Inferences::where_inferred(B));
+Problems::quote_subject(3, subj);
+Problems::quote_object(4, Inferences::get_reference_as_object(A));
+Problems::quote_object(5, Inferences::get_reference_as_object(B));
+StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_SpatialContradiction));
+Problems::issue_problem_segment(
+"You wrote %1, but also %2: that seems to be saying that the same "
+"object (%3) must be in two different places (%4 and %5). This "
+"looks like a contradiction. %P"
+"This sometimes happens as a result of a sentence like 'Every person "
+"carries a bag', when Inform doesn't know 'bag' as the name of any "
+"kind - so that it makes only a single thing called 'bag', and then "
+"the sentence looks as if it says everyone is carrying the same bag.");
+Problems::issue_problem_end();
+returnTRUE;
+ }
+returnFALSE;
+}
+
+intPL::Spatial::create_inference_families(void) {
+returnFALSE;
+}
§7. In talking about some of the fundamental spatial domains we potentially have
a vicious circle, because
@@ -263,35 +311,27 @@ multiple PARENTAGE_INF
@@ -845,7 +886,7 @@ when it's legitimately a door.
StandardProblems::contradiction_problem(_p_(PM_PersonContaining),sentence_setting_kind,
-World::Inferences::where_inferred(geography_inference), I,
+Inferences::where_inferred(geography_inference), I,"cannot contain or support things like something inanimate","which is what you are implying. Instead, people must carry or wear them: ""so 'The briefcase is in Daphne.' is disallowed, but 'The briefcase is "
@@ -861,7 +902,7 @@ Inform spatial model:
StandardProblems::contradiction_problem(_p_(PM_CantContainAndSupport),
-decider, World::Inferences::where_inferred(geography_inference), I,
+decider, Inferences::where_inferred(geography_inference), I,"cannot both contain things and support things","which is what you're implying here. If you need both, the easiest way is ""to make it either a supporter with a container attached or vice versa. "
@@ -876,7 +917,7 @@ Inform spatial model:
StandardProblems::contradiction_problem(_p_(PM_BothRoomAndSupporter),decider,
-World::Inferences::where_inferred(geography_inference), I,
+Inferences::where_inferred(geography_inference), I,"would need to have two different and incompatible kinds to make both ""sentences true","and this is a contradiction.");
@@ -907,7 +948,7 @@ provide access routines to read and write:
if (to == NULL) internal_error("set progenitor of nothing");SPATIAL_DATA(of)->progenitor = to;SPATIAL_DATA(of)->progenitor_set_at =
- (reason)?World::Inferences::where_inferred(reason):NULL;
+ (reason)?Inferences::where_inferred(reason):NULL;}
§31. This is used for error recovery only.
@@ -949,7 +990,7 @@ the kind of here-objects.
LOOP_OVER_INSTANCES(I, K_object) {SPATIAL_DATA(I)->here_flag = FALSE;inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_HERE_INF)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_HERE_INF)SPATIAL_DATA(I)->here_flag = TRUE; }
@@ -993,7 +1034,7 @@ object under investigation.
Find the inference which will decide the progenitor32.3.1;if (parent_setting_inference) {instance *whereabouts =
-World::Inferences::get_reference_as_object(parent_setting_inference);
+Inferences::get_reference_as_object(parent_setting_inference);if (SPATIAL_DATA(I)->here_flag) Find the whereabouts of something here32.3.2;if (whereabouts) {PL::Spatial::set_progenitor(I, whereabouts, parent_setting_inference);
@@ -1008,11 +1049,11 @@ object under investigation.
inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_NOWHERE_INF)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_NOWHERE_INF)Make this the determining inference32.3.1.1;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_HERE_INF)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_HERE_INF)Make this the determining inference32.3.1.1;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_INF)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PARENTAGE_INF)Make this the determining inference32.3.1.1;
if (parent_setting_inference) {StandardProblems::contradiction_problem(_p_(PM_DuplicateParentage),
-World::Inferences::where_inferred(parent_setting_inference),
-World::Inferences::where_inferred(inf),
+Inferences::where_inferred(parent_setting_inference),
+Inferences::where_inferred(inf),I,"can only be given its position once","in a single assertion sentence.");
@@ -1038,7 +1079,7 @@ object under investigation.
if (PL::Spatial::object_is_a_room(whereabouts) == FALSE) whereabouts = NULL;if (whereabouts == NULL) {parse_node *here_sentence =
-World::Inferences::where_inferred(parent_setting_inference);
+Inferences::where_inferred(parent_setting_inference);Set the whereabouts to the last discussed room prior to this inference being drawn32.3.2.1;if (whereabouts == NULL) {current_sentence = here_sentence;
@@ -1069,7 +1110,7 @@ when it finishes this will be set to the most recently mentioned.
inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PART_OF_INF) {
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PART_OF_INF) {if ((PL::Spatial::object_is_a_room(I)) || (PL::Map::object_is_a_door(I))) {StandardProblems::object_problem(_p_(PM_RoomOrDoorAsPart),I,
@@ -1408,8 +1449,8 @@ as a value for description if (K_room) {inference *inf;intdesc_seen = FALSE;
-POSITIVE_KNOWLEDGE_LOOP(inf, KindSubjects::from_kind(K_room), PROPERTY_INF)
-if (World::Inferences::get_property(inf) == P_description)
+POSITIVE_KNOWLEDGE_LOOP(inf, KindSubjects::from_kind(K_room), property_inf)
+if (PropertyInferences::get_property(inf) == P_description)desc_seen = TRUE;if (desc_seen == FALSE) {TEMPORARY_TEXT(val)
@@ -1583,8 +1624,8 @@ empty.
if (Instances::of_kind(P, K_person)) rel = "carried";if (SPATIAL_DATA(I)->part_flag) rel = "part";inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), PROPERTY_INF)
-if (World::Inferences::get_property(inf) == P_worn)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), property_inf)
+if (PropertyInferences::get_property(inf) == P_worn)rel = "worn"; }if (rel) WRITE("<i>%s</i> ", rel);
@@ -1649,8 +1690,8 @@ it already turns up under its owner.
if (Instances::of_kind(P, K_person)) rel = "carried by";if (SPATIAL_DATA(O)->part_flag) rel = "part of";inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(O), PROPERTY_INF)
-if (World::Inferences::get_property(inf) == P_worn)
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(O), property_inf)
+if (PropertyInferences::get_property(inf) == P_worn)rel = "worn by";WRITE("%s ", rel);IXInstances::index_name(OUT, P);
diff --git a/docs/if-module/3-sm2.html b/docs/if-module/3-sm2.html
index d44e76b29..2b56dc639 100644
--- a/docs/if-module/3-sm2.html
+++ b/docs/if-module/3-sm2.html
@@ -3150,7 +3150,7 @@ can make use of the following:
if (Instances::of_kind(R, K_door)) {wordingW = Instances::get_name(R, FALSE);LOG("%+W is a door.\n", W);
-parse_node *S = World::Inferences::get_prop_state(
+parse_node *S = Inferences::get_prop_state(Instances::as_subject(R), P_other_side);instance *X = Rvalues::to_object_instance(S);if (X) {
diff --git a/docs/if-module/3-sr.html b/docs/if-module/3-sr.html
index 4c48892eb..768d9f910 100644
--- a/docs/if-module/3-sr.html
+++ b/docs/if-module/3-sr.html
@@ -345,13 +345,13 @@ way which isn't symmetrical between the two, and this way round is cleanest.
§4.5. If something is being worn, it needs to have the I7 either/or property
@@ -366,12 +366,12 @@ special to make it work, so this doesn't seem worth the trouble.)
§5. Compilation. We need do nothing special: these relations can be compiled from their schemas.
diff --git a/docs/if-module/3-tm.html b/docs/if-module/3-tm.html
index 8f15f0841..84fae690b 100644
--- a/docs/if-module/3-tm.html
+++ b/docs/if-module/3-tm.html
@@ -172,7 +172,8 @@ in connection with the "mapped D of" relations, it's altogether easier and
makes for more legible code if we use a special inference type of our own:
-
defineDIRECTION_INF100 where do map connections from O lead?
+
+inference_family *DIRECTION_INF = NULL; 100; where do map connections from O lead?
§5. One useful constant:
@@ -205,6 +206,9 @@ makes for more legible code if we use a special inference type of our own:
@@ -472,9 +476,9 @@ quite crunchy algorithms, has the fastest possible access to the layout.
}LOOP_OVER_INSTANCES(I, K_object) {inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {inference_subject *infs1, *infs2;
-World::Inferences::get_references(inf, &infs1, &infs2);
+Inferences::get_references(inf, &infs1, &infs2);instance *to = NULL, *dir = NULL;if (infs1) to = InstanceSubjects::to_object_instance(infs1);if (infs2) dir = InstanceSubjects::to_object_instance(infs2);
@@ -482,7 +486,7 @@ quite crunchy algorithms, has the fastest possible access to the layout.
intdn = MAP_DATA(dir)->direction_index;if ((dn >= 0) && (dn < MAX_DIRECTIONS)) {MAP_EXIT(I, dn) = to;
-MAP_DATA(I)->exits_set_at[dn] = World::Inferences::where_inferred(inf);
+MAP_DATA(I)->exits_set_at[dn] = Inferences::where_inferred(inf); } } }
@@ -617,7 +621,7 @@ deduction is made:
if (prn == P_other_side) {instance *I = Rvalues::to_object_instance(val);if (I) {
-World::Inferences::draw(IS_ROOM_INF, Instances::as_subject(I), CERTAIN_CE,
+Inferences::draw(IS_ROOM_INF, Instances::as_subject(I), CERTAIN_CE,NULL, NULL); } }
@@ -636,7 +640,7 @@ one and Backdrops), and this is where they set it.
if (P_found_in == NULL)P_found_in = Properties::Valued::new_nameless(I"found_in",K_value);
-if (World::Inferences::get_prop_state(
+if (Inferences::get_prop_state(Instances::as_subject(I), P_found_in))internal_error("rival found_in interpretations");Properties::Valued::assert(P_found_in, Instances::as_subject(I),
@@ -651,7 +655,7 @@ and there seems little point in writing this any better.
instance *PL::Map::get_value_of_opposite_property(instance *I) {
-parse_node *val = World::Inferences::get_prop_state(
+parse_node *val = Inferences::get_prop_state(Instances::as_subject(I), P_opposite);if (val) returnRvalues::to_object_instance(val);returnNULL;
@@ -896,16 +900,16 @@ checks that various mapping impossibilities do not occur.
instance *I;LOOP_OVER_INSTANCES(I, K_object) {inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {inference_subject *infs1;
-World::Inferences::get_references(inf, &infs1, NULL);
+Inferences::get_references(inf, &infs1, NULL);instance *to = InstanceSubjects::to_object_instance(infs1);if ((PL::Spatial::object_is_a_room(I)) && (to) && (PL::Map::object_is_a_door(to) == FALSE) && (PL::Spatial::object_is_a_room(to) == FALSE))StandardProblems::contradiction_problem(_p_(PM_BadMapCell),Instances::get_creating_sentence(to),
-World::Inferences::where_inferred(inf), to,
+Inferences::where_inferred(inf), to,"appears to be something which can be reached via a map ""connection, but it seems to be neither a room nor a door","and these are the only possibilities allowed by Inform.");
@@ -932,33 +936,32 @@ checks that various mapping impossibilities do not occur.
parse_node *where[3];where[0] = NULL; where[1] = NULL; where[2] = NULL; to placate gccinference *front_side_inf = NULL, *back_side_inf = NULL;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {inference_subject *infs1, *infs2;
-World::Inferences::get_references(inf, &infs1, &infs2);
+Inferences::get_references(inf, &infs1, &infs2);instance *to = InstanceSubjects::to_object_instance(infs1);instance *dir = InstanceSubjects::to_object_instance(infs2);if (to) {if (connections_in == 0) {MAP_DATA(I)->map_connection_a = to;MAP_DATA(I)->map_direction_a = dir;
-where[0] = World::Inferences::where_inferred(inf);
+where[0] = Inferences::where_inferred(inf);front_side_inf = inf; }if (connections_in == 1) {MAP_DATA(I)->map_connection_b = to;MAP_DATA(I)->map_direction_b = dir;
-where[1] = World::Inferences::where_inferred(inf);
+where[1] = Inferences::where_inferred(inf);back_side_inf = inf; }if (connections_in == 2) {
-where[2] = World::Inferences::where_inferred(inf);
+where[2] = Inferences::where_inferred(inf); }connections_in++; } }if ((front_side_inf) && (back_side_inf)) {
-if (World::Inferences::get_timestamp(front_side_inf) >
-World::Inferences::get_timestamp(back_side_inf)) {
+if (front_side_inf->allocation_id > back_side_inf->allocation_id) {instance *X = MAP_DATA(I)->map_connection_a;MAP_DATA(I)->map_connection_a = MAP_DATA(I)->map_connection_b;MAP_DATA(I)->map_connection_b = X;
@@ -1018,9 +1021,9 @@ from which there's no way back.)
LOOP_OVER_INSTANCES(I, K_object)if (PL::Spatial::object_is_a_room(I)) {inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {
+POSITIVE_KNOWLEDGE_LOOP(inf, Instances::as_subject(I), DIRECTION_INF) {inference_subject *infs1;
-World::Inferences::get_references(inf, &infs1, NULL);
+Inferences::get_references(inf, &infs1, NULL);instance *to = InstanceSubjects::to_object_instance(infs1);if (PL::Map::object_is_a_door(to)) {instance *exit1 = MAP_DATA(to)->map_connection_a;
@@ -1063,7 +1066,7 @@ from which there's no way back.)
if ((PL::Map::object_is_a_door(I)) && (MAP_DATA(I)->map_connection_a) && (MAP_DATA(I)->map_connection_b) &&
- (World::Inferences::get_prop_state(
+ (Inferences::get_prop_state(Instances::as_subject(I), P_other_side)))StandardProblems::object_problem(_p_(PM_BothWaysDoor),I, "seems to be a door whose connections have been given in both "
@@ -1356,7 +1359,7 @@ why we don't need to compile instance *X = A;if (A == Data::Objects::room_being_indexed()) X = B;if (X == NULL) {
-parse_node *S = World::Inferences::get_prop_state(
+parse_node *S = Inferences::get_prop_state(Instances::as_subject(O), P_other_side);X = Rvalues::to_object_instance(S); }
diff --git a/docs/if-module/3-tm2.html b/docs/if-module/3-tm2.html
index db61c056b..d242cba2b 100644
--- a/docs/if-module/3-tm2.html
+++ b/docs/if-module/3-tm2.html
@@ -225,7 +225,7 @@ fact, end.
Index::anchor_numbered(OUT, sc->allocation_id);WRITE("<b>The <i>%+W</i> scene</b>", PL::Scenes::get_name(sc));Index::link(OUT, Wordings::first_wn(Node::get_text(sc->scene_declared_at)));
-if (World::Inferences::get_EO_state(
+if (Inferences::get_EO_state(Instances::as_subject(sc->as_instance), P_recurring) > 0)WRITE(" <i>recurring</i>");HTML_CLOSE("p");
@@ -417,7 +417,7 @@ on the initial call when dept
diff --git a/docs/if-module/3-tnt.html b/docs/if-module/3-tnt.html
index 17b939d6d..36510d545 100644
--- a/docs/if-module/3-tnt.html
+++ b/docs/if-module/3-tnt.html
@@ -205,9 +205,9 @@ a room called the Counting House").
voidPL::Naming::transfer_details(inference_subject *from, inference_subject *to) {instance *wto = InstanceSubjects::to_object_instance(to);if (wto) {
-if (World::Inferences::get_EO_state(from, P_proper_named) > 0)
+if (Inferences::get_EO_state(from, P_proper_named) > 0)PL::Naming::now_has_proper_name(to);
-parse_node *art = World::Inferences::get_prop_state(from, P_article);
+parse_node *art = Inferences::get_prop_state(from, P_article);if (art) Properties::Valued::assert(P_article, to, art, LIKELY_CE); }}
@@ -224,7 +224,7 @@ we do here is provide its state on request.
intPL::Naming::object_is_privately_named(instance *I) {
-intcertainty = World::Inferences::get_EO_state(Instances::as_subject(I), P_privately_named);
+intcertainty = Inferences::get_EO_state(Instances::as_subject(I), P_privately_named);if (certainty > 0) returnTRUE;if (certainty < 0) returnFALSE;returnNOT_APPLICABLE;
@@ -236,7 +236,7 @@ to fill in the naming details for objects, so here goes.
-parse_node *spec = World::Inferences::get_prop_state(subj, P_grammatical_gender);
+parse_node *spec = Inferences::get_prop_state(subj, P_grammatical_gender);if (spec) {intg = Annotations::read_int(spec, constant_enumeration_ANNOT);switch (g) {
@@ -506,9 +506,9 @@ after Y or vice versa.)
inference_subject *check;for (check = subj; check; check = InferenceSubjects::narrowest_broader_subject(check)) {inference *inf;
-POSITIVE_KNOWLEDGE_LOOP(inf, check, PROPERTY_INF)
-if (World::Inferences::added_in_construction(inf) == FALSE)
-if (World::Inferences::get_property(inf) == P_printed_name)
+POSITIVE_KNOWLEDGE_LOOP(inf, check, property_inf)
+if (Inferences::during_stage(inf) == 0)
+if (PropertyInferences::get_property(inf) == P_printed_name)returnTRUE; }returnFALSE;
@@ -658,7 +658,7 @@ this because we need access to it very quickly when parsing text substitutions.)
if (L->adaptive_person >= 0) returnL->adaptive_person;if ((L->adaptive_person == -1) && (P_adaptive_text_viewpoint)) {instance *I = L->nl_instance;
-parse_node *val = World::Inferences::get_prop_state(
+parse_node *val = Inferences::get_prop_state(Instances::as_subject(I), P_adaptive_text_viewpoint);if (Node::is(val, CONSTANT_NT)) {instance *V = Node::get_constant_instance(val);
diff --git a/docs/if-module/3-tp.html b/docs/if-module/3-tp.html
index d9e024439..22ab276c0 100644
--- a/docs/if-module/3-tp.html
+++ b/docs/if-module/3-tp.html
@@ -372,12 +372,12 @@ we assume he is freestanding in the earliest defined room.
intPL::Player::player_complete_model(intstage) {
-if ((stage == 3) && (I_yourself)) {
+if ((stage == WORLD_STAGE_III) && (I_yourself)) {P_saved_short_name = Properties::Valued::new_nameless(I"saved_short_name", K_text);Properties::Valued::assert(P_saved_short_name, Instances::as_subject(I_yourself),Rvalues::from_unescaped_wording(Feeds::feed_text(I"yourself")), CERTAIN_CE); }
-if (stage == 4) {
+if (stage == WORLD_STAGE_IV) {Set the start room to the earliest room defined in the source text11.1;If the start room is still null, there's no room, so issue a problem11.2;Otherwise see if the player has explicitly been placed in the model world11.3;
@@ -441,7 +441,7 @@ will do. But otherwise:
}inference *inf;POSITIVE_KNOWLEDGE_LOOP(inf,
-Instances::as_subject(player_character_object), PART_OF_INF) {
+Instances::as_subject(player_character_object), PART_OF_INF) {StandardProblems::object_problem(_p_(PM_PlayerIsPart),start_object,"seems to have the player attached as a component part",
diff --git a/docs/if-module/5-gp.html b/docs/if-module/5-gp.html
index 78cc6ac40..fa0c370f5 100644
--- a/docs/if-module/5-gp.html
+++ b/docs/if-module/5-gp.html
@@ -217,7 +217,7 @@ for parsing:
diff --git a/docs/index-module/2-ki.html b/docs/index-module/2-ki.html
index 380ee00c2..9831adef1 100644
--- a/docs/index-module/2-ki.html
+++ b/docs/index-module/2-ki.html
@@ -372,7 +372,7 @@ is made, so that the following sentence can't have an empty list in it.
WRITE("%S", explanation);HTML_TAG("br"); }
-World::Inferences::index(OUT, KindSubjects::from_kind(K), FALSE);
+Inferences::index(OUT, KindSubjects::from_kind(K), FALSE);
@@ -187,7 +187,7 @@ to infer from, e.g., "the ball is not green": is it red, or blue?
instance *I = RETRIEVE_POINTER_instance(am->family_specific_data);property *P = Properties::Conditions::get_coinciding_property(Instances::to_kind(I));if (P == NULL) internal_error("enumerative adjective on non-property");
-World::Inferences::draw_property(infs_to_assert_on, P, Rvalues::from_instance(I));
+PropertyInferences::draw(infs_to_assert_on, P, Rvalues::from_instance(I));returnTRUE;}
diff --git a/docs/knowledge-module/2-ins.html b/docs/knowledge-module/2-ins.html
index d628a356e..cf4954f0e 100644
--- a/docs/knowledge-module/2-ins.html
+++ b/docs/knowledge-module/2-ins.html
@@ -204,7 +204,7 @@ the same object may be thing number 17 but vehicle number 3 — and secondly
because we won't know the exact kind of objects until much later on; for now
the only thing we are sure of is that they are indeed objects. Enumeration
for objects within kinds is certainly useful, but it's harder to do and will
-be done later on: see Instance Counting.
+be done later on: see Instance Counting (in runtime).
Add the new instance to its enumeration4.3 =
@@ -245,7 +245,7 @@ be done later on: see Instance Counting
§6. Subject and source references.
-inference_subject *Instances::as_subject(instance *I) {
+inference_subject *Instances::as_subject(instance *I) {if (I == NULL) returnNULL;returnI->as_subject;}
@@ -341,13 +341,13 @@ specialised than which other ones, and by making a call, we can find out.
-kind *Instances::to_kind(instance *I) {
+kind *Instances::to_kind(instance *I) {if (I == NULL) returnNULL;inference_subject *inherits_from = InferenceSubjects::narrowest_broader_subject(I->as_subject);returnKindSubjects::to_kind(inherits_from);}
-intInstances::of_kind(instance *I, kind *match) {
+intInstances::of_kind(instance *I, kind *match) {if ((I == NULL) || (match == NULL)) returnFALSE;returnKinds::conforms_to(Instances::to_kind(I), match);}
diff --git a/docs/knowledge-module/2-nv.html b/docs/knowledge-module/2-nv.html
index 341ca2a3f..dfbc86e27 100644
--- a/docs/knowledge-module/2-nv.html
+++ b/docs/knowledge-module/2-nv.html
@@ -135,7 +135,7 @@ closer to global variables than to literals such as CLASS_DEFINITION} nonlocal_variable;
-
The structure nonlocal_variable is accessed in 2/ins, 3/prp, 3/ep, 3/vp, 3/spr, 4/vs, 5/inf, 5/cmw and here.
+
The structure nonlocal_variable is accessed in 2/ins, 3/prp, 3/ep, 3/vp, 3/spr, 4/vs, 5/inf, 5/pi, 5/tmw and here.
§2. We can create a new variable provided we give its name, kind and scope.
When the scope isn't global, the variable is said to be "stacked", which is a
reference to how it's stored at run-time.
@@ -320,10 +320,10 @@ data variable (such as "story title") to be treated as text.
wordingNonlocalVariables::initial_value_as_plain_text(nonlocal_variable *nlv) {inference *inf;inference_subject *infs = NonlocalVariables::to_subject(nlv);
-POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
-if (World::Inferences::get_property(inf) == P_variable_initial_value)
+POSITIVE_KNOWLEDGE_LOOP(inf, infs, property_inf)
+if (PropertyInferences::get_property(inf) == P_variable_initial_value)returnNode::get_text(
-World::Inferences::set_property_value_kind(inf, K_text));
+PropertyInferences::set_value_kind(inf, K_text));returnEMPTY_WORDING;}
diff --git a/docs/knowledge-module/3-cp.html b/docs/knowledge-module/3-cp.html
index 7e23b348f..a48e3ec93 100644
--- a/docs/knowledge-module/3-cp.html
+++ b/docs/knowledge-module/3-cp.html
@@ -106,7 +106,7 @@ possible values these are.)
kind *common_kind = NULL;intmixed_kind = FALSE, some_new = FALSE;wordingCKW = EMPTY_WORDING, NKW = EMPTY_WORDING;
-for (parse_node *option = set; option; option = (option->down)?(option->down->next):NULL) {
+for (parse_node *option = set; option; option = (option->down)?(option->down->next):NULL) {wordingPW = EMPTY_WORDING;if (Node::get_type(option) == AND_NT)PW = Node::get_text(option->down);
diff --git a/docs/knowledge-module/3-ep.html b/docs/knowledge-module/3-ep.html
index 39def2fc9..a8fafdc87 100644
--- a/docs/knowledge-module/3-ep.html
+++ b/docs/knowledge-module/3-ep.html
@@ -219,7 +219,7 @@ around), but not to break one.
Properties::EitherOr::make_stored_in_negation(neg);}
-property *Properties::EitherOr::get_negation(property *prn) {
+property *Properties::EitherOr::get_negation(property *prn) {if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");returnprn->negation;}
@@ -227,7 +227,7 @@ around), but not to break one.
diff --git a/docs/knowledge-module/3-epv.html b/docs/knowledge-module/3-epv.html
index 734963892..e64f5045b 100644
--- a/docs/knowledge-module/3-epv.html
+++ b/docs/knowledge-module/3-epv.html
@@ -98,17 +98,6 @@ manage that here.
Produce::annotate_i(iname, DECLARATION_ORDER_IANN, cs_sequence_counter++);Compile the actual object1.1;
-if (K) {
-World::Compile::set_rough_memory_usage(K, words_used);
-intnw = 0;
-for (inference_subject *infs = subj;
-infs; infs = InferenceSubjects::narrowest_broader_subject(infs)) {
-kind *K2 = KindSubjects::to_kind(infs);
-if (K2) nw += World::Compile::get_rough_memory_usage(K2);
- }
-nw += 16;
-LOGIF(OBJECT_COMPILATION, "Rough size estimate: %d words\n", nw);
- }LOGIF(OBJECT_COMPILATION, "Compilation of $j complete\n", subj);}
@@ -172,9 +161,9 @@ the class hierarchy at I6 level exactly match the kind hierarchy at I7 level.
inference *inf;
-KNOWLEDGE_LOOP(inf, subj, PROPERTY_INF) {
-property *prn = World::Inferences::get_property(inf);
-current_sentence = World::Inferences::where_inferred(inf);
+KNOWLEDGE_LOOP(inf, subj, property_inf) {
+property *prn = PropertyInferences::get_property(inf);
+current_sentence = Inferences::where_inferred(inf);LOGIF(OBJECT_COMPILATION, "Compiling property $Y\n", prn);words_used += Properties::Emit::emit_propertyvalue(subj, prn); }
diff --git a/docs/knowledge-module/3-ia.html b/docs/knowledge-module/3-ia.html
index 2f02fe266..0f642ef51 100644
--- a/docs/knowledge-module/3-ia.html
+++ b/docs/knowledge-module/3-ia.html
@@ -93,8 +93,8 @@ So as an interim measure the text is inferred into a pseudo-property called
voidProperties::Appearance::infer(inference_subject *infs, parse_node *spec) {inference *inf;
-KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
-if (World::Inferences::get_property(inf) == P_indefinite_appearance_text)
+KNOWLEDGE_LOOP(inf, infs, property_inf)
+if (PropertyInferences::get_property(inf) == P_indefinite_appearance_text)Issue a problem for a second appearance1.1;prevailing_mood = CERTAIN_CE;
@@ -113,7 +113,7 @@ ambiguously.
StandardProblems::infs_contradiction_problem(_p_(PM_TwoAppearances),
-World::Inferences::where_inferred(inf), current_sentence, infs,
+Inferences::where_inferred(inf), current_sentence, infs,"seems to have two different descriptions","perhaps because you intended the second description to apply to something ""mentioned in between, but declared it in such a way that it was never the "
@@ -136,12 +136,12 @@ available;
(c) But otherwise give up and issue a problem message.
-voidProperties::Appearance::reallocate(inference_subject *infs) {
+voidProperties::Appearance::reallocate(inference_subject *infs) {inference *inf;
-KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
-if (World::Inferences::get_property(inf) == P_indefinite_appearance_text) {
-parse_node *txt = World::Inferences::get_property_value(inf);
-current_sentence = World::Inferences::where_inferred(inf);
+KNOWLEDGE_LOOP(inf, infs, property_inf) {
+if (PropertyInferences::get_property(inf) == P_indefinite_appearance_text) {
+parse_node *txt = PropertyInferences::get_value(inf);
+current_sentence = Inferences::where_inferred(inf);if (Plugins::Call::default_appearance(infs, txt) == FALSE) {if ((P_description) && (World::Permissions::find(infs, P_description, TRUE))) {
diff --git a/docs/knowledge-module/3-ma.html b/docs/knowledge-module/3-ma.html
index 4a97caa45..411c7e15e 100644
--- a/docs/knowledge-module/3-ma.html
+++ b/docs/knowledge-module/3-ma.html
@@ -564,7 +564,7 @@ can't normally be unravelled at compile time.
parse_node *val = NULL;if (<s-literal>(mdef->region_threshold_text)) val = <<rp>>;elseinternal_error("literal unreadable");
-World::Inferences::draw_property(infs_to_assert_on, mdef->prop, val);
+PropertyInferences::draw(infs_to_assert_on, mdef->prop, val);returnTRUE; }returnFALSE;
diff --git a/docs/knowledge-module/3-prp.html b/docs/knowledge-module/3-prp.html
index f25e0581e..1669a614d 100644
--- a/docs/knowledge-module/3-prp.html
+++ b/docs/knowledge-module/3-prp.html
@@ -143,7 +143,7 @@ a value with the owner; it isn't that either/or properties are unloved.)
CLASS_DEFINITION} property;
-
The structure property is accessed in 2/nv, 3/ep, 3/vp, 3/cp, 3/spr, 4/vs, 5/inf, 5/cmw and here.
+
The structure property is accessed in 2/nv, 3/ep, 3/vp, 3/cp, 3/spr, 4/vs, 5/inf, 5/pi, 5/tmw and here.
§2. The only four properties which have special significance to core Inform
(though plugins are interested in many others):
diff --git a/docs/knowledge-module/3-vp.html b/docs/knowledge-module/3-vp.html
index aa4f5a0e1..2224b1e09 100644
--- a/docs/knowledge-module/3-vp.html
+++ b/docs/knowledge-module/3-vp.html
@@ -135,7 +135,7 @@ to the end user.
-property *Properties::Valued::new_nameless(text_stream *I6_form, kind *K) {
+property *Properties::Valued::new_nameless(text_stream *I6_form, kind *K) {wordingW = Feeds::feed_text(I6_form);if (K == NULL) internal_error("new nameless property without kind");package_request *R = Hierarchy::synoptic_package(PROPERTIES_HAP);
@@ -152,7 +152,7 @@ to the end user.
returnprn;}
-property *Properties::Valued::new_nameless_using(kind *K, package_request *R, inter_name *using) {
+property *Properties::Valued::new_nameless_using(kind *K, package_request *R, inter_name *using) {if (K == NULL) internal_error("new nameless property without kind");property *prn = Properties::create(EMPTY_WORDING, R, using);Properties::exclude_from_index(prn);
@@ -168,7 +168,7 @@ to the end user.
-kind *Properties::Valued::kind(property *prn) {
+kind *Properties::Valued::kind(property *prn) {if ((prn == NULL) || (prn->either_or)) returnNULL; for better type-checking Problemsreturnprn->property_value_kind;}
-voidProperties::Valued::set_kind(property *prn, kind *K) {
+voidProperties::Valued::set_kind(property *prn, kind *K) {if (K == NULL) internal_error("tried to set null kind");if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");if ((Kinds::Behaviour::definite(K) == FALSE) && (prn->do_not_compile == FALSE)) {
@@ -230,7 +230,7 @@ then say that a thing has a weight: that makes a property also called
-voidProperties::Valued::make_coincide_with_kind(property *prn, kind *K) {
+voidProperties::Valued::make_coincide_with_kind(property *prn, kind *K) {Properties::Valued::set_kind(prn, K);if (Kinds::eq(K, K_grammatical_gender)) P_grammatical_gender = prn;prn->also_a_type = TRUE;
@@ -261,7 +261,7 @@ then say that a thing has a weight: that makes a property also called
prn->stored_bp = bp;}
-binary_predicate *Properties::Valued::get_stored_relation(property *prn) {
+binary_predicate *Properties::Valued::get_stored_relation(property *prn) {if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");returnprn->stored_bp;}
@@ -280,7 +280,7 @@ all to work; the following keep a flag to mark that.
prn->used_for_non_typesafe_relation = TRUE;}
-intProperties::Valued::is_used_for_non_typesafe_relation(property *prn) {
+intProperties::Valued::is_used_for_non_typesafe_relation(property *prn) {if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");returnprn->used_for_non_typesafe_relation;}
@@ -288,7 +288,7 @@ all to work; the following keep a flag to mark that.
§10. Assertion.
-voidProperties::Valued::assert(property *prn, inference_subject *owner,
+voidProperties::Valued::assert(property *prn, inference_subject *owner,parse_node *val, intcertainty) {pcalc_prop *prop = Propositions::Abstract::to_set_property(prn, val);Assert::true_about(prop, owner, certainty);
@@ -301,7 +301,7 @@ storage methods at run-time if we wanted.)
-voidProperties::Valued::compile_value(value_holster *VH, property *prn, parse_node *val) {
+voidProperties::Valued::compile_value(value_holster *VH, property *prn, parse_node *val) {kind *K = Properties::Valued::kind(prn);if (K) Specifications::Compiler::compile_constant_to_kind_vh(VH, val, K);else {
@@ -312,7 +312,7 @@ storage methods at run-time if we wanted.)
}}
-voidProperties::Valued::compile_default_value(value_holster *VH, property *prn) {
+voidProperties::Valued::compile_default_value(value_holster *VH, property *prn) {if (Properties::Valued::is_used_for_non_typesafe_relation(prn)) {if (Holsters::data_acceptable(VH))Holsters::holster_pair(VH, LITERAL_IVAL, 0);
diff --git a/docs/knowledge-module/4-is.html b/docs/knowledge-module/4-is.html
index 2eb1e69be..338d78101 100644
--- a/docs/knowledge-module/4-is.html
+++ b/docs/knowledge-module/4-is.html
@@ -115,7 +115,7 @@ as method calls. There are (currently) five families.
returnf;}
-
The structure inference_subject_family is private to this section.
+
The structure inference_subject_family is accessed in 5/inf and here.
§2. The "fundamentals" family will be defined here. As we will see, it is used
only for a few broad concepts. It provides few method functions, because these
subjects serve a mainly organisational role.1
@@ -215,8 +215,8 @@ one and only subject with no broader subject:
structgeneral_pointerrepresents; family-specific datavoid *additional_data_for_plugins[MAX_PLUGINS]; and managed by those plugins
-structinference *inf_list; contingently true: inferences drawn about this subject
-structimplication *imp_list; necessarily true: implications applying to this
+structlinked_list *inf_list; contingently true: each inference drawn about this
+structlinked_list *imp_list; necessarily true: each implication applying to thisstructlinked_list *permissions_list; of property_permissionstructassemblies_dataassemblies; what generalisations have been made about this?
@@ -255,8 +255,8 @@ kind once the kind itself is created.)
infs->infs_created_at = current_sentence;infs->represents = gp;infs->infs_family = family;
-infs->inf_list = NULL;
-infs->imp_list = NULL;
+infs->inf_list = NEW_LINKED_LIST(inference);
+infs->imp_list = NEW_LINKED_LIST(implication);infs->broader_than = from;infs->permissions_list = NEW_LINKED_LIST(property_permission);infs->infs_name_in_log = log_name;
@@ -275,7 +275,7 @@ It has to do with the difference between "yourself" and "the player".
infs->alias_variable = q;}
-intInferenceSubjects::aliased_but_diverted(inference_subject *infs) {
+intInferenceSubjects::aliased_but_diverted(inference_subject *infs) {if (infs->alias_variable) {inference_subject *vs =Instances::as_subject(
@@ -296,7 +296,7 @@ This makes testing for containment simple:
-intInferenceSubjects::is_within(inference_subject *smaller, inference_subject *larger) {
+intInferenceSubjects::is_within(inference_subject *smaller, inference_subject *larger) {while (smaller) {if (smaller == larger) returnTRUE;smaller = smaller->broader_than;
@@ -314,7 +314,7 @@ operations scaling the subject tree, we use the following:
To manage the individual pieces of information gathered, with varying degrees of certainty, from assertion sentences. This is mostly information about which objects have what properties.
§1. Inform reads a natural language description of a world. As it runs through, it
collects together the assertions made in this description (such as "On the
@@ -113,14 +113,7 @@ about X or Y.
by the fact in question, besides the INFS to which it is attached.
-
§2. There are only two main types of inference, though plugins can and do define
-further types.
-
-
-
defineARBITRARY_RELATION_INF1 fact about an "arbitrary" relation
-definePROPERTY_INF2 fact about a property
-
-
§3. Not all information is positive, or certain. The likelihood of something
+
§2. Not all information is positive, or certain. The likelihood of something
being true is measured on the five-point *_CE scale, though an inference
is never allowed to have UNKNOWN_CE status — that would tell us nothing.
@@ -130,18 +123,87 @@ certainty". Thus there are only three absolute certainty levels: unknown,
likely and certain.
-
§4. This is the data structure used to store a single inference. Within the
-stock of facts known about a given INFS, the individual inferences are
-organised as linked lists; hence the next field.
-
typedefstructinference {
-intinference_type; see above
+inference_family *family; see aboveintcertainty; see above
-structparse_node *inferred_from; from what sentence was this drawn?
-intadded_in_construction; or was this drawn during the model completion stage?
-intinference_timestamp;
+general_pointerdata;structinference_subject *infs_ref1; from 0 to 2 other INFSs are connected by this inferencestructinference_subject *infs_ref2;
@@ -149,74 +211,57 @@ organised as linked lists; hence the structparse_node *spec_ref1; used by dynamic relations between non-subjectsstructparse_node *spec_ref2;
-structproperty *inferred_property; property referred to, if any
-structparse_node *inferred_property_value; and its value, if any
-
-structinference *next; next in list of inferences on same subject
+structparse_node *inferred_from; from what sentence was this drawn?
+intdrawn_during_stage; or was this drawn during the model completion stage?CLASS_DEFINITION} inference;
-
The structure inference is accessed in 3/ps, 3/cp, 4/is and here.
-
§5. Creation. The following routine coins a newly minted inference which is not yet attached
+
The structure inference is accessed in 1/ap, 2/iaa, 3/ep, 5/pi and here.
+
§9. Creation. The following routine coins a newly minted inference which is not yet attached
to any subject: but it will not stay unattached for long. Note that if nothing
has been said about likelihood, the sentence is assumed to be factually certain.
§7. Drawing inferences. This is how the rest of Inform records fresh information about the world
+
§11. Drawing inferences. This is how the rest of Inform records fresh information about the world
model. To "draw" an inference is to create it as a structure and then
"join" it to the list of facts already known about its subject. (This
might not actually accept it; it might be redundant, or contradictory.)
@@ -226,134 +271,106 @@ might not actually accept it; it might be redundant, or contradictory.)
§10. Core Inform deals only in INFSs, but plugins often use inferences concerned
+
§14. Core Inform deals only in INFSs, but plugins often use inferences concerned
only with objects (e.g., for the map), so we also provide a convenient abbreviated
way to extract just reference 1 in object form.
§11. Looping over inferences. The following macro prototypes show how to loop through all of the inferences
+
§15. Looping over inferences. The following macro prototypes show how to loop through all of the inferences
known concerning a given inference subject, and of a given type. "Positive"
knowledge means that the inferences must have a certainty of likely or better.
§16. Comparing inferences. The following routine is a little like strcmp, the standard C routine
+
§20. Comparing inferences. The following routine is a little like strcmp, the standard C routine
for comparing strings, in that it compares two inferences and returns a
value useful for sorting algorithms: 0 if equal, positive if i1 < i2,
negative if i2 < i1. This is a stable trichotomy; in particular,
@@ -622,7 +639,7 @@ same property but with different values.
defineCI_DIFFER_IN_COPY_ONLY7defineCI_IDENTICAL0
-
§17. Funny story: until 2019, this routine ran by using pointer subtraction when
+
§21. Funny story: until 2019, this routine ran by using pointer subtraction when
comparing, for example, the INFS references in the inferences, on the principle
that the ordering doesn't really matter so long as it is definite and stable
during a run. But in the late 2010s, desktop operating systems such as MacOS
@@ -640,66 +657,61 @@ was probably a good thing.
§18. Joining an inference to what is known about an object. As the above will have made clear, it is not altogether easy to join a new
+
§22. Joining an inference to what is known about an object. As the above will have made clear, it is not altogether easy to join a new
inference to the linked list of inferences which belong to a given subject: we
can't simply put it at the end of the list. The following routine looks simple
enough, but was a difficult one to get right.
@@ -724,51 +736,51 @@ then the routine exits without completing the loop.
§22.2. The first question we must answer is when our two inferences are talking
about what is basically the same fact. We do this by requiring that the
-absolute value of the World::Inferences::compare_inferences score — which will always be
+absolute value of the Inferences::compare_inferences score — which will always be
one of the CI_* constants enumerated above — must exceed some threshold.
(Recall that higher scores mean greater similarity; the perfect CI_IDENTICAL
is not possible here.)
@@ -779,7 +791,7 @@ always at least half-way down the list, so we can be certain that
(and therefore it's unambiguous what we mean by the type of inference being
looked at). For two property inferences to be talking about the same fact,
@@ -794,55 +806,50 @@ never talk about the same fact unless they're essentially identical.
belonging to plugins (at present, anyway).
-
Determine the affinity threshold, which depends on the inference type18.2 =
+
Determine the affinity threshold, which depends on the inference type22.2 =
§22.3.3. Contradictions of certainty are forbidden, so issue a problem22.3.3 =
-World::Inferences::report_inference(i, infs, "contradiction");
-World::Inferences::report_inference(list, infs, "with");
-if ((list->inference_type != PROPERTY_INF) &&
- (list->inference_type != ARBITRARY_RELATION_INF) &&
+Inferences::report_inference(i, infs, "contradiction");
+Inferences::report_inference(list, infs, "with");
+ if ((list->family != property_inf) &&
+ (list->family != arbitrary_relation_inf) && (Plugins::Call::explain_contradiction(list, i, d, infs))) return;
-if (i->inference_type == PROPERTY_INF) {
-if (i->inferred_property == P_variable_initial_value)
-StandardProblems::two_sentences_problem(_p_(PM_VariableContradiction),
-list->inferred_from,
-"this looks like a contradiction",
-"because the initial value of this variable seems to be being set "
-"in each of these sentences, but with a different outcome.");
-else {
-if (Properties::is_value_property(i->inferred_property)) {
-binary_predicate *bp =
-Properties::Valued::get_stored_relation(i->inferred_property);
-if (bp) {
-if (Wordings::match(Node::get_text(current_sentence), Node::get_text(list->inferred_from))) {
-Problems::quote_source(1, current_sentence);
-Problems::quote_relation(3, bp);
-Problems::quote_subject(4, infs);
-Problems::quote_spec(5, i->inferred_property_value);
-Problems::quote_spec(6, list->inferred_property_value);
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_RelationContradiction2));
-Problems::issue_problem_segment(
-"I'm finding a contradiction at the sentence %1, "
-"because it means I can't set up %3. "
-"On the one hand, %4 should relate to %5, but on the other "
-"hand to %6, and this is a relation which doesn't allow "
-"such clashes.");
-Problems::issue_problem_end();
- } else {
-Problems::quote_source(1, current_sentence);
-Problems::quote_source(2, list->inferred_from);
-Problems::quote_relation(3, bp);
-Problems::quote_subject(4, infs);
-Problems::quote_spec(5, i->inferred_property_value);
-Problems::quote_spec(6, list->inferred_property_value);
-StandardProblems::handmade_problem(Task::syntax_tree(), _p_(PM_RelationContradiction));
-Problems::issue_problem_segment(
-"I'm finding a contradiction at the sentences %1 and %2, "
-"because between them they set up rival versions of %3. "
-"On the one hand, %4 should relate to %5, but on the other "
-"hand to %6, and this is a relation which doesn't allow "
-"such clashes.");
-Problems::issue_problem_end();
- }
-return;
- }
- }
-StandardProblems::two_sentences_problem(_p_(PM_PropertyContradiction),
-list->inferred_from,
-"this looks like a contradiction",
-"because the same property seems to be being set in each of these sentences, "
-"but with a different outcome.");
- }
- } else
- #ifdefIF_MODULE
-if (i->inference_type == IS_ROOM_INF) {
-StandardProblems::two_sentences_problem(_p_(PM_WhenIsARoomNotARoom),
-list->inferred_from,
-"this looks like a contradiction",
-"because apparently something would have to be both a room and not a "
-"room at the same time.");
- } else
- #endif
-StandardProblems::two_sentences_problem(_p_(PM_Contradiction),
-list->inferred_from,
-"this looks like a contradiction",
-"which might be because I have misunderstood what was meant to be the subject "
-"of one or both of those sentences.");
+*/
+if (Inferences::explain_contradiction(list, i, d, infs)) return;
+StandardProblems::two_sentences_problem(_p_(PM_Contradiction),
+list->inferred_from,
+"this looks like a contradiction",
+"which might be because I have misunderstood what was meant to be the subject "
+"of one or both of those sentences.");return;
§22.3.4. When talking about kinds or kinds of value, we allow new merely likely
information to displace old; but not when talking about specific objects or
values, when the initial information stands. (This is to make it easier for
people to change the effect of extensions which create kinds and specify their
likely properties.)
-
Later uncertain data beats earlier, for subjects which generalise about whole domains18.3.4 =
+
Later uncertain data beats earlier, for subjects which generalise about whole domains22.3.4 =
§23. Logging inferences. We keep the debugging log file more than usually well informed about what
goes on with inferences, as there is obviously great potential for mystifying
bugs if inferences are incorrectly ignored.
To enforce the domain of properties: for instance, that a door can be open or closed but that an animal cannot, or that a person can have a carrying capacity but that a door cannot.
@@ -128,7 +128,7 @@ whereas the unpredictable order might make testing Inform more annoying.
LOOP_OVER_LINKED_LIST(pp, property_permission, InferenceSubjects::get_permissions(infs))
-property_permission *World::Permissions::find(inference_subject *infs,
+property_permission *World::Permissions::find(inference_subject *infs,property *prn, intallow_inheritance) {property *prnbar = NULL;if (Properties::is_either_or(prn)) prnbar = Properties::EitherOr::get_negation(prn);
@@ -240,7 +240,7 @@ in the case of a broken jar.
}
Once the assertions have all been read and reduced to inferences, and all the creations have been made, we take stock; sometimes we spot inconsistencies, sometimes we make deductions, and we try to complete our picture of the model world.
§1. Stages II to IV. The process of using existing facts to infer new ones is vulnerable
-to timing bugs, so we organise the "making" process into five numbered
-stages, given the Roman numerals I to V. Much of the work is done by plugins,
-which can take a hand at any or all of the stages, using their contextual
-knowledge to fill in missing properties.
-
-
-
(I) Deducing the kind of any object whose kind is not known. Because this
-can result in a change of kind, which can result in further creations by
-assembly sentences like "A handle is part of every door", Stage I takes
-place at the end of traverse 2 of the source text and, uniquely, gets the
-opportunity to add fresh sentences to the source — thus extending the
-traverse. By the end of Stage I, all kinds are fixed.
-
(II) Stages II and III are for adding further properties or relationships,
-which aren't explicit in the source text but which plugins can add on the
-basis of contextual understanding. (Two stages are provided here to avoid
-timing issues where one plugin has to act earlier than another.)
-
(III) See (II). If a plugin is going to change the compilation order of
-the objects (as the spatial-model plugin does), it must do so during
-Stage III.
-
(IV) A stage for consistency checks or to store away useful data, but where
-nothing in the model may be changed — no properties or relationships
-may be added. (Except that the instance-counting plugin is allowed to
-add the linked-lists-of-instances properties, used to optimise loops
-at run-time; they aren't visible at the I7 level so aren't properly
-part of the model world.)
-
(V) A final chance to add properties which will assist the run-time
-implementation of, for instance, the command grammar, but again aren't
-really part of the model world. (This can't be done earlier since the
-command grammar isn't parsed until after World::complete; and we
-aren't allowed to add I7-accessible properties.)
-
-
The following routine, then, carries out stages II, III and IV.
+
§1. Introduction. World-building has five stages, written with Roman numerals I to V in this
+source code. The logic in this section is all quite simple, but plugins are
+allowed to intervene at each of the five stages, bringing domain-specific
+wisdom to the process.
+
defineWORLD_STAGE_I1 Deduce kinds for object instances
+defineWORLD_STAGE_II2 First chance to add further properties or relationships
+defineWORLD_STAGE_III3 Second chance to add further properties or relationships
+defineWORLD_STAGE_IV4 Perform mutual consistency checks
+defineWORLD_STAGE_V5 Post-game: only implementation details can be added
+
-voidWorld::complete(void) {
-Stages II and III of the completion process1.1;
-Stage IV of the completion process1.2;
+intcurrent_model_world_stage = 0; not yet building the world model
+
+voidWorld::ask_plugins_at_stage(intS) {
+if (S != current_model_world_stage + 1) internal_error("Stage mistimed");
+current_model_world_stage = S;
+Plugins::Call::complete_model(S);
+}
+
+intWorld::current_building_stage(void) {
+returncurrent_model_world_stage;}
-
§1.1. The model world is a broth with many cooks. On the one hand, we have the
-various different INFSs, with their different needs — a various-to-various
-relation, a global variable, and so on — and on the other hand we also
-have the plugins, each of which takes its own global view of the situation.
-We give everyone a turn.
+
§2. Stage I. Deducing the kind of any object whose kind is not known. The core compiler
+has already done the best it can, but then it lacks domain-specific
+understanding. So the only business done is by plugins, which understand
+certain kinds and relationships better.
-
Stages II and III of the completion process1.1 =
+
Some instances change their kinds in Stage I, and this can result in further
+creations by assembly sentences like "A handle is part of every door". Because
+of that, Stage I takes place at the end of traverse 2 of the source text and,
+uniquely, gets the opportunity to add fresh sentences to the source — thus
+extending the traverse. But by the end of Stage I, all kinds are fixed, and
+no further instances can be created.
§3. Stages II and III. This is an opportunity for plugins to add further properties or relationships
+on the basis of contextual understanding. Two stages, and thus two opportunities,
+are provided here to avoid timing issues where one plugin has to act earlier
+than another.
+
+
+
If a plugin is going to change the compilation order of the objects (as the
+spatial-model plugin does), it must do so during Stage III, not Stage II.
+
+
+
+voidWorld::stages_II_and_III(void) {inference_subject *infs;LOOP_OVER(infs, inference_subject) {InferenceSubjects::complete_model(infs);
@@ -125,28 +137,27 @@ We give everyone a turn.
}LOOP_OVER(infs, inference_subject)Assertions::Implications::consider_all(infs);
-Plugins::Call::complete_model(2);
-Plugins::Call::complete_model(3);
+World::ask_plugins_at_stage(WORLD_STAGE_II);
+World::ask_plugins_at_stage(WORLD_STAGE_III);
+}
§1.2. Checking what we have, then. Once again each INFS is given an opportunity
-to check itself, and then the plugins have a turn.
-
-
-
Stage IV of the completion process1.2 =
+
§4. Stage IV. This is for consistency checks or to store away useful data, but where
+nothing in the model may be changed — no properties or relationships
+may be added.
§1.2.1. These two checks may seem a little odd. After all, we've been throwing out
+
§4.1. These two checks may seem a little odd. After all, we've been throwing out
impossible inferences with problem messages all along, while reading the
source text. Why not perform these checks then, too?
@@ -173,13 +184,13 @@ in plugins which add inconsistent properties.
A nameless property added in Stages II and III does not need permission.
§4.2. The following contradiction checks do not apply to properties added
+in Stages II and III, since those are often Inter hacks added for run-time
convenience, and don't have to follow the I7 rules.
-
Check that properties are not contradictory1.2.2 =
+
§4.2.1.1. It's never a problem when a vague fact about something general is contradicted
by a fact about something specific; the problem comes with something like this:
@@ -243,17 +255,17 @@ rather than LIKELY_CE<
about the Portal, to stand.
-
Check that these differently scoped inferences do not clash1.2.2.1.1 =
+
Check that these differently scoped inferences do not clash4.2.1.1 =
§4.2.1.1.1. Issue a problem message for clash with wider inference4.2.1.1.1 =
LOG("Checking infs $j compatible with infs $j for property $Y:\n $I\n $I\n",infs, boss, prn, narrow, wide);StandardProblems::infs_contradiction_problem(_p_(PM_InstanceContradiction),
-World::Inferences::where_inferred(narrow), World::Inferences::where_inferred(wide), infs,
+Inferences::where_inferred(narrow), Inferences::where_inferred(wide), infs,"therefore has to have two contradictory states of the same property at once","which is impossible. When a kind's definition says that something is 'always' ""true, there is no way to override that for particular things of the kind.");
§5. Stage V. A final chance to add properties which may assist the run-time implementation
+of whatever a plugin is concerned with, but which is not allowed to make
+changes to the model as it would be understood by the author.
+
+
+
For example, the Instance Counting (in runtime) plugin adds low-level properties
+to improve run-time performance, but they have no names and cannot be referred
+to or accessed by code written in Inform 7; they exist at the level of Inter only.
diff --git a/docs/knowledge-module/P-wtmd.html b/docs/knowledge-module/P-wtmd.html
index f62a58693..220979521 100644
--- a/docs/knowledge-module/P-wtmd.html
+++ b/docs/knowledge-module/P-wtmd.html
@@ -132,17 +132,10 @@ proposition to a set of facts concerning things in the model; as we have
seen, the model includes kinds, variables, instances and relations, and so
we need a unified type for "something you can know a fact about". That
type is called inference_subject. Each subject has its own list of known
-facts: we call such a fact an inference because it has (usually) been
+facts: we call such a fact an inference because it has (usually) been
inferred from a proposition.
-
Chapter 3: Properties implements our system of properties: each different value
or either-or property is a property object. There might be a puritan
case for abolishing this type in favour of regarding either-or properties
@@ -151,7 +144,16 @@ of binary_predicate
-
Finally, Chapter 5: Modelling deals with the actual inferences, and with how the
+model world is constructed. The core of Inform does nothing very interesting
+here, but plugins from the if module add some domain-specific savvy.
diff --git a/docs/runtime-module/4-cl.html b/docs/runtime-module/4-cl.html
index 1e6b8f42c..4335f9c28 100644
--- a/docs/runtime-module/4-cl.html
+++ b/docs/runtime-module/4-cl.html
@@ -160,7 +160,7 @@ the list!);
}
diff --git a/docs/runtime-module/4-es.html b/docs/runtime-module/4-es.html
index 34521abfd..16daca001 100644
--- a/docs/runtime-module/4-es.html
+++ b/docs/runtime-module/4-es.html
@@ -89,7 +89,7 @@ they provide values different from each other and from all other functions.
}
diff --git a/docs/runtime-module/4-fc.html b/docs/runtime-module/4-fc.html
index 73f666b79..c79a4796b 100644
--- a/docs/runtime-module/4-fc.html
+++ b/docs/runtime-module/4-fc.html
@@ -216,7 +216,7 @@ Inform's own version number), but it belongs nowhere else either, so:
}
A plugin which maintains run-time-accessible linked lists of instances of kinds, in order to speed up loops; and instance counts within kinds, in order to speed up relation storage; and the object-kind hierarchy, in order to speed up run-time checking of the type safety of property usage.
§1. Every subject contains a pointer to its own unique copy of the following
structure, but it only has relevance if the subject represents an object:
@@ -96,8 +96,8 @@ structure, but it only has relevance if the subject represents an object:
typedefstructcounting_data {
-structproperty *instance_count_prop; the (I6 only) IK-Count property for this kind
-structproperty *instance_link_prop; the (I6 only) IK-Link property for this kind
+structproperty *instance_count_prop; the (I6 only) IK-Count property for this kind
+structproperty *instance_link_prop; the (I6 only) IK-Link property for this kindinthas_instances; are there any instances of this kind?CLASS_DEFINITION} counting_data;
@@ -109,29 +109,29 @@ route-finding through relations on objects.
-property *P_vector = NULL;
-property *P_KD_Count = NULL; see below
+property *P_vector = NULL;
+property *P_KD_Count = NULL; see below
§5.2. The following is quadratic in the number of objects, but this has never been
a problem in practice; the number seldom exceeds a few hundred.
@@ -179,7 +179,7 @@ a problem in practice; the number seldom exceeds a few hundred.
-instance *I;
+instance *I;kind *K;LOOP_OVER_BASE_KINDS(K)if (Kinds::Behaviour::is_subkind_of_object(K))
@@ -193,12 +193,12 @@ a problem in practice; the number seldom exceeds a few hundred.
INSTANCE_COUNT(I, K) = ix_count++; }
§11.3.1. As noted above, KD_Count is a special case. This looks as if it should be
the instance count of "kind" itself, but that would be useless, since no
instance object can ever have kind "kind" — instances aren't kinds.
@@ -426,12 +426,12 @@ usage is legal.
§11.3.2. And otherwise, for every kind that the instance belongs to (directly or
indirectly) it gets the relevant instance count as a property value. For
example, the red door might have IK4_Count set to 3 — it's door number 3,
@@ -446,11 +446,11 @@ and so on for all other kinds.
diff --git a/docs/runtime-module/4-itc.html b/docs/runtime-module/4-itc.html
index 3227d43d6..abc194ed8 100644
--- a/docs/runtime-module/4-itc.html
+++ b/docs/runtime-module/4-itc.html
@@ -563,7 +563,7 @@ only and may change at any time without notice.
diff --git a/docs/runtime-module/4-ni.html b/docs/runtime-module/4-ni.html
index 46f22b90d..5dcf56fab 100644
--- a/docs/runtime-module/4-ni.html
+++ b/docs/runtime-module/4-ni.html
@@ -159,7 +159,7 @@ instance, the Standard Rules want the player-character object to be called
}
@@ -2153,9 +2153,9 @@ matches the specific necessary kind of object if there is one.
packaging_statesave = Routines::begin(RTRelations::initialiser_iname(bp));inference *i;inter_name *rtiname = Hierarchy::find(RELATIONTEST_HL);
-POSITIVE_KNOWLEDGE_LOOP(i, World::Inferences::bp_as_subject(bp), ARBITRARY_RELATION_INF) {
+POSITIVE_KNOWLEDGE_LOOP(i, Inferences::bp_as_subject(bp), arbitrary_relation_inf) {parse_node *spec0, *spec1;
-World::Inferences::get_references_spec(i, &spec0, &spec1);
+Inferences::get_references_spec(i, &spec0, &spec1);RTRelations::mark_as_needed(bp);Produce::inv_call_iname(Emit::tree(), rtiname);Produce::down(Emit::tree());
@@ -2175,7 +2175,7 @@ matches the specific necessary kind of object if there is one.
}
diff --git a/docs/runtime-module/4-rsfk.html b/docs/runtime-module/4-rsfk.html
index 905e29eab..ba034f140 100644
--- a/docs/runtime-module/4-rsfk.html
+++ b/docs/runtime-module/4-rsfk.html
@@ -131,7 +131,7 @@ kinds being compiled to an I6 returnNULL;}
-intRTKinds::I6_classnumber(kind *K) {
+intRTKinds::I6_classnumber(kind *K) {returnKinds::Behaviour::get_range_number(K);}
@@ -1129,7 +1129,7 @@ each such kind, and needed at run-time.
diff --git a/docs/runtime-module/4-rsp.html b/docs/runtime-module/4-rsp.html
index 69a100cc9..bc7d4bfae 100644
--- a/docs/runtime-module/4-rsp.html
+++ b/docs/runtime-module/4-rsp.html
@@ -697,7 +697,7 @@ text needs to be printed in a particular way.
diff --git a/docs/runtime-module/4-rtn.html b/docs/runtime-module/4-rtn.html
index 8b2a4f691..03af8b600 100644
--- a/docs/runtime-module/4-rtn.html
+++ b/docs/runtime-module/4-rtn.html
@@ -307,7 +307,7 @@ after the call parameters, and is used only as a scratch variable.
diff --git a/docs/runtime-module/4-ts.html b/docs/runtime-module/4-ts.html
index d324e7281..02db387f2 100644
--- a/docs/runtime-module/4-ts.html
+++ b/docs/runtime-module/4-ts.html
@@ -460,7 +460,7 @@ we aren't doing very much; most TSs will be passed quickly over.
}
diff --git a/docs/runtime-module/4-tv.html b/docs/runtime-module/4-tv.html
index a7df96677..b403a3fcc 100644
--- a/docs/runtime-module/4-tv.html
+++ b/docs/runtime-module/4-tv.html
@@ -169,7 +169,7 @@ hacky constructs which only the SR should ever refer to.
}
diff --git a/docs/runtime-module/4-vrb.html b/docs/runtime-module/4-vrb.html
index 680588847..b31089bde 100644
--- a/docs/runtime-module/4-vrb.html
+++ b/docs/runtime-module/4-vrb.html
@@ -476,7 +476,7 @@ which makes its kind safe. Hence the error messages.
-
+ A plugin which maintains run-time-accessible linked lists of instances of kinds, in order to speed up loops; and instance counts within kinds, in order to speed up relation storage; and the object-kind hierarchy, in order to speed up run-time checking of the type safety of property usage.
+