diff --git a/docs/if-module/1-im.html b/docs/if-module/1-im.html
index ef4a18a98..73c6e3f32 100644
--- a/docs/if-module/1-im.html
+++ b/docs/if-module/1-im.html
@@ -169,7 +169,7 @@ nothing except to be a parent to them; it has no activation function.
map_plugin = PluginManager::new (& PL::Map::start , I "mapping" , ifp );
persons_plugin = PluginManager::new (& PL::Persons::start , I "persons" , ifp );
player_plugin = PluginManager::new (& Player::start , I "player" , ifp );
- regions_plugin = PluginManager::new (& PL::Regions::start , I "regions" , ifp );
+ regions_plugin = PluginManager::new (& Regions::start , I "regions" , ifp );
scenes_plugin = PluginManager::new (& PL::Scenes::start , I "scenes" , ifp );
scoring_plugin = PluginManager::new (& PL::Score::start , I "scoring" , ifp );
showme_plugin = PluginManager::new (& PL::Showme::start , I "showme" , ifp );
diff --git a/docs/if-module/3-em.html b/docs/if-module/3-em.html
index 432ae083a..ccb40df74 100644
--- a/docs/if-module/3-em.html
+++ b/docs/if-module/3-em.html
@@ -290,7 +290,7 @@ If all are null, then the global scope is used.
if ( scope_I ) {
if ( Spatial::object_is_a_room ( scope_I ))
scope = PL::EPSMap::scope_for_single_room ( scope_I );
- else if ( PL::Regions::object_is_a_region ( scope_I )) {
+ else if ( Regions::object_is_a_region ( scope_I )) {
instance * rm ;
LOOP_OVER_INSTANCES ( rm , K_room )
if ( PL::EPSMap::obj_in_region ( rm , scope_I ))
@@ -321,8 +321,8 @@ If all are null, then the global scope is used.
int PL::EPSMap::obj_in_region ( instance * I , instance * reg ) {
if (( I == NULL ) || ( reg == NULL )) return FALSE ;
- if ( PL::Regions::enclosing ( I ) == reg ) return TRUE ;
- return PL::EPSMap::obj_in_region ( PL::Regions::enclosing ( I ), reg );
+ if ( Regions::enclosing ( I ) == reg ) return TRUE ;
+ return PL::EPSMap::obj_in_region ( Regions::enclosing ( I ), reg );
}
-void PL::HTMLMap::colour_chip ( OUTPUT_STREAM , instance * I , instance * Reg , parse_node * at ) {
+void PL::HTMLMap::colour_chip ( OUTPUT_STREAM , instance * I , instance * Reg , parse_node * at ) {
HTML_OPEN_WITH ( "table" ,
"border=\"%d\" cellpadding=\"0\" cellspacing=\"0\" "
"bordercolor=\"#%s\" height=\"%d\"" ,
@@ -1319,7 +1319,7 @@ that nothing is shown if all of the rooms are outside of regions.
int count = 0 ;
instance * R ;
LOOP_OVER_ROOMS ( R ) {
- if ( PL::Regions::enclosing ( R ) == reg ) {
+ if ( Regions::enclosing ( R ) == reg ) {
if ( count ++ == 0 ) {
Start the region key table for this region 13.1 ;
} else {
diff --git a/docs/if-module/3-rgn.html b/docs/if-module/3-rgn.html
index 09e286ccc..8c39b9b6d 100644
--- a/docs/if-module/3-rgn.html
+++ b/docs/if-module/3-rgn.html
@@ -73,115 +73,80 @@ function togglePopup(material_id) {
A plugin providing support for grouping rooms together into named and nestable regions.
-
-
-
-binary_predicate * R_regional_containment = NULL ;
+void Regions::start ( void ) {
+ PluginManager::plug ( CREATE_INFERENCE_SUBJECTS_PLUG , Regions::create_inference_subjects );
+ PluginManager::plug ( NEW_BASE_KIND_NOTIFY_PLUG , Regions::new_base_kind_notify );
+ PluginManager::plug ( SET_SUBKIND_NOTIFY_PLUG , Regions::set_subkind_notify );
+ PluginManager::plug ( NEW_SUBJECT_NOTIFY_PLUG , Regions::new_subject_notify );
+ PluginManager::plug ( NEW_PROPERTY_NOTIFY_PLUG , Regions::new_property_notify );
+ PluginManager::plug ( COMPLETE_MODEL_PLUG , Regions::complete_model );
+ PluginManager::plug ( MORE_SPECIFIC_PLUG , Regions::more_specific );
+ PluginManager::plug ( INTERVENE_IN_ASSERTION_PLUG , Regions::intervene_in_assertion );
+ PluginManager::plug ( NAME_TO_EARLY_INFS_PLUG , Regions::name_to_early_infs );
+ PluginManager::plug ( ADD_TO_WORLD_INDEX_PLUG , IXRegions::add_to_World_index );
+ PluginManager::plug ( PRODUCTION_LINE_PLUG , Regions::production_line );
+}
+
+int Regions::production_line ( int stage , int debugging ,
+ stopwatch_timer * sequence_timer ) {
+ if ( stage == INTER1_CSEQ ) {
+ BENCH ( RTRegions::write_found_in_functions );
+ }
+ return FALSE ;
+}
-
kind * K_region = NULL ;
inference_subject * infs_region = NULL ;
-property * P_map_region = NULL ;
-property * P_regional_found_in = NULL ;
-
-
-define REGIONS_DATA ( I ) PLUGIN_DATA_ON_INSTANCE ( regions , I )
-
-
-typedef struct regions_data {
- struct instance * in_region ;
- struct parse_node * in_region_set_at ;
- struct inter_name * in_region_iname ;
- CLASS_DEFINITION
-} regions_data ;
-
-The structure regions_data is private to this section.
-
-
-
-void PL::Regions::start ( void ) {
- PluginManager::plug ( CREATE_INFERENCE_SUBJECTS_PLUG , PL::Regions::create_inference_subjects );
- PluginManager::plug ( NEW_BASE_KIND_NOTIFY_PLUG , PL::Regions::regions_new_base_kind_notify );
- PluginManager::plug ( SET_SUBKIND_NOTIFY_PLUG , PL::Regions::regions_set_subkind_notify );
- PluginManager::plug ( NEW_SUBJECT_NOTIFY_PLUG , PL::Regions::regions_new_subject_notify );
- PluginManager::plug ( NEW_PROPERTY_NOTIFY_PLUG , PL::Regions::regions_new_property_notify );
- PluginManager::plug ( COMPLETE_MODEL_PLUG , PL::Regions::regions_complete_model );
- PluginManager::plug ( MORE_SPECIFIC_PLUG , PL::Regions::regions_more_specific );
- PluginManager::plug ( INTERVENE_IN_ASSERTION_PLUG , PL::Regions::regions_intervene_in_assertion );
- PluginManager::plug ( NAME_TO_EARLY_INFS_PLUG , PL::Regions::regions_name_to_early_infs );
- PluginManager::plug ( ADD_TO_WORLD_INDEX_PLUG , PL::Regions::regions_add_to_World_index );
- PluginManager::plug ( PRODUCTION_LINE_PLUG , PL::Regions::production_line );
-}
-
-int PL::Regions::production_line ( int stage , int debugging ,
- stopwatch_timer * sequence_timer ) {
- if ( stage == INTER1_CSEQ ) {
- BENCH ( PL::Regions::write_regional_found_in_routines );
- }
- return FALSE ;
-}
-
-int PL::Regions::create_inference_subjects ( void ) {
- infs_region = InferenceSubjects::new_fundamental ( global_constants , "region(early)" );
- return FALSE ;
-}
-
-regions_data * PL::Regions::new_data ( inference_subject * subj ) {
- regions_data * rd = CREATE ( regions_data );
- rd -> in_region = NULL ;
- rd -> in_region_set_at = NULL ;
- rd -> in_region_iname = NULL ;
- return rd ;
-}
-
-inter_name * PL::Regions::found_in_iname ( instance * I ) {
- if ( REGIONS_DATA ( I )-> in_region_iname == NULL )
- REGIONS_DATA ( I )-> in_region_iname = Hierarchy::make_iname_in ( REGION_FOUND_IN_FN_HL , RTInstances::package ( I ));
- return REGIONS_DATA ( I )-> in_region_iname ;
-}
-
-
+
<notable-regions-kinds> ::=
region
This is Preform grammar , not regular C code.
-
+
-int PL::Regions::regions_new_base_kind_notify ( kind * new_base , char * text_stream , wording W ) {
+int Regions::new_base_kind_notify ( kind * new_base , char * text_stream , wording W ) {
if ( <notable-regions-kinds> ( W )) {
K_region = new_base ; return TRUE ;
}
return FALSE ;
}
-
-int PL::Regions::regions_new_subject_notify ( inference_subject * subj ) {
- ATTACH_PLUGIN_DATA_TO_SUBJECT ( regions , subj , PL::Regions::new_data ( subj ));
- return FALSE ;
-}
-
-int PL::Regions::regions_set_subkind_notify ( kind * sub , kind * super ) {
+int Regions::create_inference_subjects ( void ) {
+ infs_region = InferenceSubjects::new_fundamental ( global_constants , "region(early)" );
+ return FALSE ;
+}
+int Regions::name_to_early_infs ( wording W , inference_subject ** infs ) {
+ if (( <notable-regions-kinds> ( W )) && ( K_region == NULL )) * infs = infs_region ;
+ return FALSE ;
+}
+
+
+
+
+int Regions::set_subkind_notify ( kind * sub , kind * super ) {
if (( sub == K_region ) && ( super != K_object )) {
if ( problem_count == 0 )
StandardProblems::sentence_problem ( Task::syntax_tree (), _p_ ( PM_RegionAdrift ),
@@ -194,22 +159,28 @@ there is no need to translate this to other languages.)
return FALSE ;
}
-
+
-int PL::Regions::object_is_a_region ( instance * I ) {
- if (( K_region ) && ( I ) && ( Instances::of_kind ( I , K_region ))) return TRUE ;
- return FALSE ;
+instance * Regions::enclosing ( instance * reg ) {
+ instance * P = NULL ;
+ if ( Spatial::object_is_a_room ( reg )) P = REGIONS_DATA ( reg )-> in_region ;
+ if ( Regions::object_is_a_region ( reg )) P = Spatial::progenitor ( reg );
+ if ( Regions::object_is_a_region ( P ) == FALSE ) return NULL ;
+ return P ;
}
-
-int PL::Regions::regions_more_specific ( instance * I1 , instance * I2 ) {
+int Regions::more_specific ( instance * I1 , instance * I2 ) {
int r1 = Instances::of_kind ( I1 , K_room );
int r2 = Instances::of_kind ( I2 , K_room );
int reg1 = Instances::of_kind ( I1 , K_region );
@@ -223,7 +194,42 @@ domains.)
return 0 ;
}
-
+
+
+int Regions::object_is_a_region ( instance * I ) {
+ if (( K_region ) && ( I ) && ( Instances::of_kind ( I , K_region ))) return TRUE ;
+ return FALSE ;
+}
+
+
+
+define REGIONS_DATA ( I ) PLUGIN_DATA_ON_INSTANCE ( regions , I )
+
+
+typedef struct regions_data {
+ struct instance * in_region ;
+ struct parse_node * in_region_set_at ;
+ struct inter_name * in_region_iname ;
+ CLASS_DEFINITION
+} regions_data ;
+
+int Regions::new_subject_notify ( inference_subject * subj ) {
+ regions_data * rd = CREATE ( regions_data );
+ rd -> in_region = NULL ;
+ rd -> in_region_set_at = NULL ;
+ rd -> in_region_iname = NULL ;
+ ATTACH_PLUGIN_DATA_TO_SUBJECT ( regions , subj , rd );
+ return FALSE ;
+}
+
+The structure regions_data is private to this section.
+
@@ -233,21 +239,22 @@ Standard Rules. (So there is no need to translate this to other languages.)
map region
This is Preform grammar , not regular C code.
-
+
-int PL::Regions::regions_new_property_notify ( property * prn ) {
+property * P_map_region = NULL ;
+int Regions::new_property_notify ( property * prn ) {
if ( <notable-regions-properties>(prn-> name ))
P_map_region = prn ;
return FALSE ;
}
-
-int PL::Regions::regions_intervene_in_assertion ( parse_node * px , parse_node * py ) {
+int Regions::intervene_in_assertion ( parse_node * px , parse_node * py ) {
if (( Node::get_type ( px ) == PROPER_NOUN_NT ) &&
( Node::get_type ( py ) == COMMON_NOUN_NT )) {
inference_subject * left_subject = Node::get_subject ( px );
@@ -285,140 +292,24 @@ messages which would have been less helpful if core Inform had produced them.
return FALSE ;
}
-
+
-int PL::Regions::regions_name_to_early_infs ( wording W , inference_subject ** infs ) {
- if (( <notable-regions-kinds> ( W )) && ( K_region == NULL )) * infs = infs_region ;
+int Regions::complete_model ( int stage ) {
+ if ( stage == WORLD_STAGE_II ) Assert map-region properties of rooms and regions 14.1 ;
+ if ( stage == WORLD_STAGE_III ) Assert regional-found-in properties of regions 14.2 ;
return FALSE ;
}
-
-
-
-void PL::Regions::create_relations ( void ) {
- R_regional_containment =
- BinaryPredicates::make_pair ( spatial_bp_family ,
- BPTerms::new ( infs_region ),
- BPTerms::new ( KindSubjects::from_kind ( K_object )),
- I "region-contains" , I "in-region" ,
- NULL , Calculus::Schemas::new ( "TestRegionalContainment(*2,*1)" ),
- PreformUtilities::wording ( <relation-names> ,
- REGIONAL_CONTAINMENT_RELATION_NAME ));
- BinaryPredicates::set_index_details ( R_regional_containment , NULL , "room/region" );
-}
-
-
-
-
-int PL::Regions::assert_relations ( binary_predicate * relation ,
- instance * I0 , instance * I1 ) {
- int I0_is_region = FALSE ;
- if ( Instances::of_kind ( I0 , K_region )) I0_is_region = TRUE ;
- int I1_is_region = FALSE ;
- if ( Instances::of_kind ( I1 , K_region )) I1_is_region = TRUE ;
-
- if ( I0_is_region ) {
- if (( relation == R_incorporation ) ||
- ( relation == R_containment ) ||
- ( relation == R_regional_containment )) {
- You can only be declared as in one region 15.1 ;
- if ( I1_is_region ) A region is being put inside a region 15.2
- else A room is being put inside a region 15.3 ;
- } else {
- StandardProblems::sentence_problem ( Task::syntax_tree (), _p_ ( PM_RegionRelation ),
- "regions can only contain rooms" ,
- "and have no other relationships." );
- }
- return TRUE ;
- } else if ( I1_is_region ) {
- if (( relation == R_incorporation ) ||
- ( relation == R_containment ) ||
- ( relation == R_regional_containment )) {
- StandardProblems::sentence_problem ( Task::syntax_tree (), _p_ ( PM_RegionRelation2 ),
- "regions can only be contained in other regions" ,
- "and not for example in rooms." );
- }
- }
-
- return FALSE ;
-}
-
-
-
-
- if (( REGIONS_DATA ( I1 )-> in_region ) &&
- ( REGIONS_DATA ( I1 )-> in_region != I0 )) {
- StandardProblems::sentence_problem ( Task::syntax_tree (), _p_ ( PM_RegionInTwoRegions ),
- "each region can only be declared to be inside a single "
- "other region" ,
- "since although regions can be placed inside each other, "
- "they are not permitted to overlap." );
- return TRUE ;
- }
- REGIONS_DATA ( I1 )-> in_region = I0 ;
- REGIONS_DATA ( I1 )-> in_region_set_at = current_sentence ;
-
-This code is used in §15 .
-
-
-
- inference_subject * inner = Instances::as_subject ( I1 );
- inference_subject * outer = Instances::as_subject ( I0 );
- SpatialInferences::infer_parentage ( inner , CERTAIN_CE , outer );
-
-This code is used in §15 .
-
-
-
-
-
- inference_subject * rm = Instances::as_subject ( I1 );
- parse_node * spec = Rvalues::from_instance ( I0 );
- Propositions::Abstract::assert_kind_of_instance ( I1 , K_room );
- PropertyInferences::draw ( rm , P_map_region , spec );
-
-This code is used in §15 .
-
-
-
-instance * PL::Regions::enclosing ( instance * reg ) {
- instance * P = NULL ;
- if ( Spatial::object_is_a_room ( reg )) P = REGIONS_DATA ( reg )-> in_region ;
- if ( PL::Regions::object_is_a_region ( reg )) P = Spatial::progenitor ( reg );
- if ( PL::Regions::object_is_a_region ( P ) == FALSE ) return NULL ;
- return P ;
-}
-
-
-
-
-int PL::Regions::regions_complete_model ( int stage ) {
- if ( stage == WORLD_STAGE_II ) Assert map-region properties of rooms and regions 17.1 ;
- if ( stage == WORLD_STAGE_III ) Assert regional-found-in properties of regions 17.2 ;
- return FALSE ;
-}
-
-
A desert room is a kind of room. The map region of a desert room is usually Sahara.
-
@@ -437,59 +328,127 @@ region is either the next broadest region containing it, or else }
}
-This code is used in §17 .
-This code is used in §14 .
+
- P_regional_found_in = ValueProperties::new_nameless (
+ property * P_regional_found_in = ValueProperties::new_nameless (
I "regional_found_in" , K_text );
instance * I ;
LOOP_OVER_INSTANCES ( I , K_object )
if ( Instances::of_kind ( I , K_region )) {
- inter_name * iname = PL::Regions::found_in_iname ( I );
+ inter_name * iname = RTRegions::found_in_iname ( I );
ValueProperties::assert ( P_regional_found_in , Instances::as_subject ( I ),
Rvalues::from_iname ( iname ), CERTAIN_CE );
}
-This code is used in §17 .
-
+This code is used in §14 .
+
-void PL::Regions::write_regional_found_in_routines ( void ) {
- instance * I ;
- LOOP_OVER_INSTANCES ( I , K_object )
- if ( Instances::of_kind ( I , K_region )) {
- inter_name * iname = PL::Regions::found_in_iname ( I );
- packaging_state save = Routines::begin ( iname );
- Produce::inv_primitive ( Emit::tree (), IF_BIP );
- Produce::down ( Emit::tree ());
- Produce::inv_call_iname ( Emit::tree (), Hierarchy::find ( TESTREGIONALCONTAINMENT_HL ));
- Produce::down ( Emit::tree ());
- Produce::val_iname ( Emit::tree (), K_object , Hierarchy::find ( LOCATION_HL ));
- Produce::val_iname ( Emit::tree (), K_object , RTInstances::iname ( I ));
- Produce::up ( Emit::tree ());
- Produce::code ( Emit::tree ());
- Produce::down ( Emit::tree ());
- Produce::rtrue ( Emit::tree ());
- Produce::up ( Emit::tree ());
- Produce::up ( Emit::tree ());
- Produce::rfalse ( Emit::tree ());
- Routines::end ( save );
- }
+binary_predicate * R_regional_containment = NULL ;
+
+
+
+
+void Regions::create_relations ( void ) {
+ R_regional_containment =
+ BinaryPredicates::make_pair ( spatial_bp_family ,
+ BPTerms::new ( infs_region ),
+ BPTerms::new ( KindSubjects::from_kind ( K_object )),
+ I "region-contains" , I "in-region" ,
+ NULL , Calculus::Schemas::new ( "TestRegionalContainment(*2,*1)" ),
+ PreformUtilities::wording ( <relation-names> ,
+ REGIONAL_CONTAINMENT_RELATION_NAME ));
+ BinaryPredicates::set_index_details ( R_regional_containment , NULL , "room/region" );
}
-
+
-int PL::Regions::regions_add_to_World_index ( OUTPUT_STREAM , instance * O ) {
- if (( O ) && ( Instances::of_kind ( O , K_room ))) {
- instance * R = PL::Regions::enclosing ( O );
- if ( R ) PL::HTMLMap::colour_chip ( OUT , O , R , REGIONS_DATA ( O )-> in_region_set_at );
+int Regions::assert_relations ( binary_predicate * relation ,
+ instance * I0 , instance * I1 ) {
+ int I0_is_region = FALSE ;
+ if ( Instances::of_kind ( I0 , K_region )) I0_is_region = TRUE ;
+ int I1_is_region = FALSE ;
+ if ( Instances::of_kind ( I1 , K_region )) I1_is_region = TRUE ;
+
+ if ( I0_is_region ) {
+ if (( relation == R_incorporation ) ||
+ ( relation == R_containment ) ||
+ ( relation == R_regional_containment )) {
+ You can only be declared as in one region 17.1 ;
+ if ( I1_is_region ) A region is being put inside a region 17.2
+ else A room is being put inside a region 17.3 ;
+ } else {
+ StandardProblems::sentence_problem ( Task::syntax_tree (),
+ _p_ ( PM_RegionRelation ),
+ "regions can only contain rooms" ,
+ "and have no other relationships." );
+ }
+ return TRUE ;
+ } else if ( I1_is_region ) {
+ if (( relation == R_incorporation ) ||
+ ( relation == R_containment ) ||
+ ( relation == R_regional_containment )) {
+ StandardProblems::sentence_problem ( Task::syntax_tree (),
+ _p_ ( PM_RegionRelation2 ),
+ "regions can only be contained in other regions" ,
+ "and not for example in rooms." );
+ }
}
+
return FALSE ;
}
+
+
+
+ if (( REGIONS_DATA ( I1 )-> in_region ) &&
+ ( REGIONS_DATA ( I1 )-> in_region != I0 )) {
+ StandardProblems::sentence_problem ( Task::syntax_tree (),
+ _p_ ( PM_RegionInTwoRegions ),
+ "each region can only be declared to be inside a single "
+ "other region" ,
+ "since although regions can be placed inside each other, "
+ "they are not permitted to overlap." );
+ return TRUE ;
+ }
+ REGIONS_DATA ( I1 )-> in_region = I0 ;
+ REGIONS_DATA ( I1 )-> in_region_set_at = current_sentence ;
+
+This code is used in §17 .
+
+
+
+ inference_subject * inner = Instances::as_subject ( I1 );
+ inference_subject * outer = Instances::as_subject ( I0 );
+ SpatialInferences::infer_parentage ( inner , CERTAIN_CE , outer );
+
+This code is used in §17 .
+
+
+
+
+
+ inference_subject * rm = Instances::as_subject ( I1 );
+ parse_node * spec = Rvalues::from_instance ( I0 );
+ Propositions::Abstract::assert_kind_of_instance ( I1 , K_room );
+ PropertyInferences::draw ( rm , P_map_region , spec );
+
+This code is used in §17 .
diff --git a/docs/if-module/3-si.html b/docs/if-module/3-si.html
index b3ca30c1a..9b4d0da38 100644
--- a/docs/if-module/3-si.html
+++ b/docs/if-module/3-si.html
@@ -149,7 +149,7 @@ indications of spatial structure:
CLASS_DEFINITION
} parentage_inference_data ;
-void SpatialInferences::infer_parentage ( inference_subject * inner , int certitude ,
+void SpatialInferences::infer_parentage ( inference_subject * inner , int certitude ,
inference_subject * outer ) {
parentage_inference_data * data = CREATE ( parentage_inference_data );
data -> parent = InferenceSubjects::divert ( outer );
diff --git a/docs/if-module/3-sm.html b/docs/if-module/3-sm.html
index 6d69f29e1..a7c759b33 100644
--- a/docs/if-module/3-sm.html
+++ b/docs/if-module/3-sm.html
@@ -209,7 +209,7 @@ of vehicle, and so on, but this would cause mayhem in the model world. So:
-int Spatial::object_is_a_room ( instance * I ) {
+int Spatial::object_is_a_room ( instance * I ) {
if (( K_room ) && ( I ) && ( Instances::of_kind ( I , K_room ))) return TRUE ;
return FALSE ;
}
@@ -809,7 +809,7 @@ provide access routines to read and write:
-instance * Spatial::progenitor ( instance * I ) {
+instance * Spatial::progenitor ( instance * I ) {
if ( I == NULL ) return NULL ;
if ( PluginManager::active ( spatial_plugin ) == FALSE ) return NULL ;
return SPATIAL_DATA ( I )-> progenitor ;
@@ -877,7 +877,7 @@ the kind of here-objects.
if (( Spatial::progenitor ( I )) &&
( Instances::of_kind ( I , K_thing ) == FALSE ) &&
( Instances::of_kind ( I , K_room ) == FALSE ) &&
- ( PL::Regions::object_is_a_region ( I ) == FALSE )) {
+ ( Regions::object_is_a_region ( I ) == FALSE )) {
Problems::quote_source (1, Instances::get_creating_sentence ( I ));
Problems::quote_object (2, I );
Problems::quote_object (3, Spatial::progenitor ( I ));
@@ -1139,7 +1139,7 @@ which depend on Spatial whether or not one object spatially contains another:
-int Spatial::encloses ( instance * I1 , instance * I2 ) {
+int Spatial::encloses ( instance * I1 , instance * I2 ) {
while ( I1 ) {
I1 = Spatial::progenitor ( I1 );
if ( I1 == I2 ) return TRUE ;
diff --git a/docs/if-module/3-sm2.html b/docs/if-module/3-sm2.html
index cd9887d02..ac1171d9f 100644
--- a/docs/if-module/3-sm2.html
+++ b/docs/if-module/3-sm2.html
@@ -2880,8 +2880,8 @@ contain.
instance * R1 = mc1 -> first_room_in_submap ;
instance * R2 = mc2 -> first_room_in_submap ;
if (( R1 ) && ( R2 )) {
- instance * reg1 = PL::Regions::enclosing ( R1 );
- instance * reg2 = PL::Regions::enclosing ( R2 );
+ instance * reg1 = Regions::enclosing ( R1 );
+ instance * reg2 = Regions::enclosing ( R2 );
if (( reg1 ) && ( reg2 == NULL )) return -1;
if (( reg1 == NULL ) && ( reg2 )) return 1 ;
if ( reg1 ) {
@@ -3013,12 +3013,12 @@ running time in check.
if ( sub -> bounds . population == 1 ) {
instance * R = sub -> first_room_in_submap ;
if ( R ) {
- instance * reg = PL::Regions::enclosing ( R );
+ instance * reg = Regions::enclosing ( R );
if ( reg ) {
instance * S , * closest_S = NULL ;
int closest = 0 ;
LOOP_OVER_ROOMS ( S )
- if (( S != R ) && ( PL::Regions::enclosing ( S ) == reg ))
+ if (( S != R ) && ( Regions::enclosing ( S ) == reg ))
if (( posnd == FALSE ) || ( MAP_DATA ( S )-> submap -> positioned )) {
int diff = 2 *( R -> allocation_id - S -> allocation_id );
if ( diff < 0 ) diff = 1 - diff ;
@@ -3167,7 +3167,7 @@ can make use of the following:
if ( Instances::of_kind ( R , K_room )) {
wording RW = Instances::get_name ( R , FALSE );
LOG ( "%+W is a room.\n" , RW );
- instance * reg = PL::Regions::enclosing ( R );
+ instance * reg = Regions::enclosing ( R );
if ( reg ) {
wording RGW = Instances::get_name ( reg , FALSE );
if ( MAP_DATA ( reg )-> zone == 1 ) {
diff --git a/docs/if-module/3-sr.html b/docs/if-module/3-sr.html
index df813a219..78581ad9d 100644
--- a/docs/if-module/3-sr.html
+++ b/docs/if-module/3-sr.html
@@ -124,7 +124,7 @@ MathJax = {
Make built-in spatial relationships 2.1 ;
Make built-in indirect spatial relationships 2.2 ;
PL::MapDirections::create_relations ();
- PL::Regions::create_relations ();
+ Regions::create_relations ();
}
}
@@ -311,7 +311,7 @@ way which isn't symmetrical between the two, and this way round is cleanest.
if ( Backdrops::assert_relations ( bp , I0 , I1 )) return TRUE ;
if ( PL::MapDirections::assert_relations ( bp , I0 , I1 )) return TRUE ;
- if ( PL::Regions::assert_relations ( bp , I0 , I1 )) return TRUE ;
+ if ( Regions::assert_relations ( bp , I0 , I1 )) return TRUE ;
instance * reg ;
LOOP_OVER_INSTANCES ( reg , K_object )
- if ( PL::Regions::object_is_a_region ( reg )) {
+ if ( Regions::object_is_a_region ( reg )) {
int subheaded = FALSE ;
IXInstances::increment_indexing_count ( reg );
instance * rm ;
LOOP_OVER_INSTANCES ( rm , K_object )
if (( Spatial::object_is_a_room ( rm )) &&
- ( PL::Regions::enclosing ( rm ) == reg )) {
+ ( Regions::enclosing ( rm ) == reg )) {
if ( subheaded == FALSE ) {
Start a new details panel on the World index 2.2.2 ;
Index the name and super-region of the region 2.2.1 ;
@@ -178,7 +178,7 @@ instance) Spatial.
WRITE ( "<b>The <i>%+W</i> region" , Instances::get_name ( reg , FALSE ));
- instance * within = PL::Regions::enclosing ( reg );
+ instance * within = Regions::enclosing ( reg );
if ( within ) WRITE ( " within the <i>%+W</i> region" , Instances::get_name ( within , FALSE ));
WRITE ( "</b>" );
diff --git a/docs/index-module/3-bck.html b/docs/index-module/3-bck.html
index 07d8d04ec..5e0923356 100644
--- a/docs/index-module/3-bck.html
+++ b/docs/index-module/3-bck.html
@@ -119,7 +119,7 @@ adds backdrop contents to a room called
+
diff --git a/docs/index-module/3-ef.html b/docs/index-module/3-ef.html
index 1de046be1..ef821e60f 100644
--- a/docs/index-module/3-ef.html
+++ b/docs/index-module/3-ef.html
@@ -119,7 +119,7 @@ function togglePopup(material_id) {
}
+
diff --git a/docs/index-module/3-fgr.html b/docs/index-module/3-fgr.html
index 1711ccf37..db57af468 100644
--- a/docs/index-module/3-fgr.html
+++ b/docs/index-module/3-fgr.html
@@ -165,7 +165,7 @@ to match this width, preserving the aspect ratio.
}
+
diff --git a/docs/index-module/3-rgn.html b/docs/index-module/3-rgn.html
new file mode 100644
index 000000000..1a49090d5
--- /dev/null
+++ b/docs/index-module/3-rgn.html
@@ -0,0 +1,85 @@
+
+
+
+ Regions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Compiler Webs Inbuild Modules Inform7 Modules Inter Modules Services
+
+
+
+
+Indexing the player's initial position.
+
+
+
+
+int IXRegions::add_to_World_index ( OUTPUT_STREAM , instance * O ) {
+ if (( O ) && ( Instances::of_kind ( O , K_room ))) {
+ instance * R = Regions::enclosing ( O );
+ if ( R ) PL::HTMLMap::colour_chip ( OUT , O , R , REGIONS_DATA ( O )-> in_region_set_at );
+ }
+ return FALSE ;
+}
+
+
+
+
+
+
+
+
diff --git a/docs/index-module/3-se.html b/docs/index-module/3-se.html
index b956d687b..2019ae71c 100644
--- a/docs/index-module/3-se.html
+++ b/docs/index-module/3-se.html
@@ -191,7 +191,7 @@ function togglePopup(material_id) {
}
+
diff --git a/docs/index-module/3-spt.html b/docs/index-module/3-spt.html
index b19a89774..444ac27da 100644
--- a/docs/index-module/3-spt.html
+++ b/docs/index-module/3-spt.html
@@ -165,7 +165,7 @@ it already turns up under its owner.
}
+
diff --git a/docs/index-module/3-tp.html b/docs/index-module/3-tp.html
index 5649263e2..1c17e0ab3 100644
--- a/docs/index-module/3-tp.html
+++ b/docs/index-module/3-tp.html
@@ -93,7 +93,7 @@ usually appear anywhere.
}
+
diff --git a/docs/index-module/index.html b/docs/index-module/index.html
index fa33ab67a..c9752abb3 100644
--- a/docs/index-module/index.html
+++ b/docs/index-module/index.html
@@ -179,6 +179,11 @@
Backdrops -
Indexing the player's initial position.
+
+
+ Regions -
+ Indexing the player's initial position.
+
diff --git a/docs/runtime-module/2-emt.html b/docs/runtime-module/2-emt.html
index 91fc9b9af..f3c1f42eb 100644
--- a/docs/runtime-module/2-emt.html
+++ b/docs/runtime-module/2-emt.html
@@ -84,7 +84,7 @@ function togglePopup(material_id) {
inter_tree * I7_generation_tree = NULL ;
-inter_tree * Emit::tree ( void ) {
+inter_tree * Emit::tree ( void ) {
return I7_generation_tree ;
}
diff --git a/docs/runtime-module/2-hrr.html b/docs/runtime-module/2-hrr.html
index 93f0cdb9e..2ffefae58 100644
--- a/docs/runtime-module/2-hrr.html
+++ b/docs/runtime-module/2-hrr.html
@@ -1723,7 +1723,7 @@ function togglePopup(material_id) {
-inter_name * Hierarchy::find ( int id ) {
+inter_name * Hierarchy::find ( int id ) {
return HierarchyLocations::find ( Emit::tree (), id );
}
@@ -1755,7 +1755,7 @@ function togglePopup(material_id) {
return HierarchyLocations::attach_new_package ( Emit::tree (), NULL , super , hap_id );
}
-inter_name * Hierarchy::make_iname_in ( int id , package_request * P ) {
+inter_name * Hierarchy::make_iname_in ( int id , package_request * P ) {
return HierarchyLocations::find_in_package ( Emit::tree (), id , P , EMPTY_WORDING , NULL , -1, NULL );
}
diff --git a/docs/runtime-module/4-ins.html b/docs/runtime-module/4-ins.html
index a6c399818..ebdfbb961 100644
--- a/docs/runtime-module/4-ins.html
+++ b/docs/runtime-module/4-ins.html
@@ -91,7 +91,7 @@ function togglePopup(material_id) {
I -> icd . instance_emitted = FALSE ;
}
-inter_name * RTInstances::iname ( instance * I ) {
+inter_name * RTInstances::iname ( instance * I ) {
if ( I == NULL ) return NULL ;
return I -> icd . instance_iname ;
}
@@ -154,7 +154,7 @@ declarations) and finally return
+
diff --git a/docs/runtime-module/5-ef.html b/docs/runtime-module/5-ef.html
index e15641294..3c9600fc9 100644
--- a/docs/runtime-module/5-ef.html
+++ b/docs/runtime-module/5-ef.html
@@ -129,7 +129,7 @@
The structure external_file_compilation_data is private to this section.
+
diff --git a/docs/runtime-module/5-fgr.html b/docs/runtime-module/5-fgr.html
index 14a4bea82..5144230dc 100644
--- a/docs/runtime-module/5-fgr.html
+++ b/docs/runtime-module/5-fgr.html
@@ -77,7 +77,7 @@
}
+
diff --git a/docs/runtime-module/5-nmn.html b/docs/runtime-module/5-nmn.html
index 2a92e8654..568400d18 100644
--- a/docs/runtime-module/5-nmn.html
+++ b/docs/runtime-module/5-nmn.html
@@ -186,7 +186,7 @@ function togglePopup(material_id) {
The structure short_name_notice is private to this section.
+
diff --git a/docs/runtime-module/5-prs.html b/docs/runtime-module/5-prs.html
index 0c965cd6c..248511a91 100644
--- a/docs/runtime-module/5-prs.html
+++ b/docs/runtime-module/5-prs.html
@@ -148,7 +148,7 @@ for the kinds we inherit from.
}
+
diff --git a/docs/runtime-module/5-rgn.html b/docs/runtime-module/5-rgn.html
new file mode 100644
index 000000000..4db728449
--- /dev/null
+++ b/docs/runtime-module/5-rgn.html
@@ -0,0 +1,117 @@
+
+
+
+ Regions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Compiler Webs Inbuild Modules Inform7 Modules Inter Modules Services
+
+
+
+
+
+
+
+inter_name * RTRegions::found_in_iname ( instance * I ) {
+ if ( REGIONS_DATA ( I )-> in_region_iname == NULL )
+ REGIONS_DATA ( I )-> in_region_iname =
+ Hierarchy::make_iname_in ( REGION_FOUND_IN_FN_HL , RTInstances::package ( I ));
+ return REGIONS_DATA ( I )-> in_region_iname ;
+}
+
+
+
+
+void RTRegions::write_found_in_functions ( void ) {
+ instance * I ;
+ LOOP_OVER_INSTANCES ( I , K_object )
+ if ( Instances::of_kind ( I , K_region )) {
+ inter_name * iname = RTRegions::found_in_iname ( I );
+ packaging_state save = Routines::begin ( iname );
+ Produce::inv_primitive ( Emit::tree (), IF_BIP );
+ Produce::down ( Emit::tree ());
+ Produce::inv_call_iname ( Emit::tree (),
+ Hierarchy::find ( TESTREGIONALCONTAINMENT_HL ));
+ Produce::down ( Emit::tree ());
+ Produce::val_iname ( Emit::tree (), K_object , Hierarchy::find ( LOCATION_HL ));
+ Produce::val_iname ( Emit::tree (), K_object , RTInstances::iname ( I ));
+ Produce::up ( Emit::tree ());
+ Produce::code ( Emit::tree ());
+ Produce::down ( Emit::tree ());
+ Produce::rtrue ( Emit::tree ());
+ Produce::up ( Emit::tree ());
+ Produce::up ( Emit::tree ());
+ Produce::rfalse ( Emit::tree ());
+ Routines::end ( save );
+ }
+}
+
+
+
+
+
+
+
+
diff --git a/docs/runtime-module/5-se.html b/docs/runtime-module/5-se.html
index f7e188158..77c3a136d 100644
--- a/docs/runtime-module/5-se.html
+++ b/docs/runtime-module/5-se.html
@@ -77,7 +77,7 @@
}
+
diff --git a/docs/runtime-module/5-spt.html b/docs/runtime-module/5-spt.html
index 96598fbd2..4bd08d380 100644
--- a/docs/runtime-module/5-spt.html
+++ b/docs/runtime-module/5-spt.html
@@ -142,7 +142,7 @@ be compiled, so this code is never used.
}
+
diff --git a/docs/runtime-module/5-tp.html b/docs/runtime-module/5-tp.html
index 6374e0686..4680cd41f 100644
--- a/docs/runtime-module/5-tp.html
+++ b/docs/runtime-module/5-tp.html
@@ -114,7 +114,7 @@ the function -
+
+
+ Regions -
+
+
diff --git a/inform7/Figures/memory-diagnostics.txt b/inform7/Figures/memory-diagnostics.txt
index c9d62b2a8..3755f9377 100644
--- a/inform7/Figures/memory-diagnostics.txt
+++ b/inform7/Figures/memory-diagnostics.txt
@@ -228,7 +228,7 @@ Total memory consumption was 258576K = 253 MB
37.5% was used for memory not allocated for objects:
- 15.9% text stream storage 42248412 bytes in 265816 claims
+ 15.9% text stream storage 42248372 bytes in 265816 claims
3.5% dictionary storage 9278976 bytes in 16372 claims
---- sorting 1064 bytes in 3 claims
2.7% source text 7200000 bytes in 3 claims
diff --git a/inform7/Figures/timings-diagnostics.txt b/inform7/Figures/timings-diagnostics.txt
index b03a3a521..afede8724 100644
--- a/inform7/Figures/timings-diagnostics.txt
+++ b/inform7/Figures/timings-diagnostics.txt
@@ -1,15 +1,15 @@
100.0% in inform7 run
- 67.0% in compilation to Inter
- 25.7% in //Phrases::Manager::compile_first_block//
+ 67.8% in compilation to Inter
+ 25.8% in //Phrases::Manager::compile_first_block//
8.9% in //Phrases::Manager::compile_as_needed//
- 7.0% in //Strings::compile_responses//
- 6.1% in //InferenceSubjects::emit_all//
- 4.1% in //MajorNodes::pre_pass//
- 3.2% in //MajorNodes::pass_1//
- 1.9% in //Phrases::Manager::RulePrintingRule_routine//
- 1.7% in //Phrases::Manager::rulebooks_array//
- 1.0% in //RTVerbs::ConjugateVerb//
- 0.8% in //Phrases::Manager::traverse//
+ 6.7% in //Strings::compile_responses//
+ 6.4% in //InferenceSubjects::emit_all//
+ 4.4% in //MajorNodes::pre_pass//
+ 3.4% in //MajorNodes::pass_1//
+ 2.0% in //Phrases::Manager::RulePrintingRule_routine//
+ 1.8% in //Phrases::Manager::rulebooks_array//
+ 0.9% in //Phrases::Manager::traverse//
+ 0.9% in //RTVerbs::ConjugateVerb//
0.5% in //Phrases::Manager::parse_rule_parameters//
0.5% in //World::stage_V//
0.3% in //MajorNodes::pass_2//
@@ -19,11 +19,11 @@
0.1% in //RTKinds::compile_data_type_support_routines//
0.1% in //Task::make_built_in_kind_constructors//
0.1% in //World::stages_II_and_III//
- 3.2% not specifically accounted for
- 30.5% in running Inter pipeline
- 10.2% in step preparation
- 9.7% in inter step 2/12: link
- 7.0% in inter step 12/12: generate inform6 -> auto.inf
+ 3.3% not specifically accounted for
+ 29.7% in running Inter pipeline
+ 9.7% in step preparation
+ 9.5% in inter step 2/12: link
+ 6.9% in inter step 12/12: generate inform6 -> auto.inf
0.3% in inter step 9/12: make-identifiers-unique
0.1% in inter step 10/12: reconcile-verbs
0.1% in inter step 11/12: eliminate-redundant-labels
@@ -31,6 +31,6 @@
0.1% in inter step 6/12: assimilate
0.1% in inter step 7/12: resolve-external-symbols
0.1% in inter step 8/12: inspect-plugs
- 2.1% not specifically accounted for
- 1.9% in supervisor
+ 2.0% not specifically accounted for
+ 2.0% in supervisor
0.4% not specifically accounted for
diff --git a/inform7/if-module/Chapter 1/IF Module.w b/inform7/if-module/Chapter 1/IF Module.w
index bb971b380..c7751f9d3 100644
--- a/inform7/if-module/Chapter 1/IF Module.w
+++ b/inform7/if-module/Chapter 1/IF Module.w
@@ -83,7 +83,7 @@ void IFModule::create_plugins(void) {
map_plugin = PluginManager::new(&PL::Map::start, I"mapping", ifp);
persons_plugin = PluginManager::new(&PL::Persons::start, I"persons", ifp);
player_plugin = PluginManager::new(&Player::start, I"player", ifp);
- regions_plugin = PluginManager::new(&PL::Regions::start, I"regions", ifp);
+ regions_plugin = PluginManager::new(&Regions::start, I"regions", ifp);
scenes_plugin = PluginManager::new(&PL::Scenes::start, I"scenes", ifp);
scoring_plugin = PluginManager::new(&PL::Score::start, I"scoring", ifp);
showme_plugin = PluginManager::new(&PL::Showme::start, I"showme", ifp);
diff --git a/inform7/if-module/Chapter 3/EPS Map.w b/inform7/if-module/Chapter 3/EPS Map.w
index 4e05e7c85..02455c89f 100644
--- a/inform7/if-module/Chapter 3/EPS Map.w
+++ b/inform7/if-module/Chapter 3/EPS Map.w
@@ -190,7 +190,7 @@ void PL::EPSMap::put_mp(wchar_t *name, map_parameter_scope *scope, instance *sco
if (scope_I) {
if (Spatial::object_is_a_room(scope_I))
scope = PL::EPSMap::scope_for_single_room(scope_I);
- else if (PL::Regions::object_is_a_region(scope_I)) {
+ else if (Regions::object_is_a_region(scope_I)) {
instance *rm;
LOOP_OVER_INSTANCES(rm, K_room)
if (PL::EPSMap::obj_in_region(rm, scope_I))
@@ -221,8 +221,8 @@ map_parameter_scope *PL::EPSMap::scope_for_single_room(instance *rm) {
int PL::EPSMap::obj_in_region(instance *I, instance *reg) {
if ((I == NULL) || (reg == NULL)) return FALSE;
- if (PL::Regions::enclosing(I) == reg) return TRUE;
- return PL::EPSMap::obj_in_region(PL::Regions::enclosing(I), reg);
+ if (Regions::enclosing(I) == reg) return TRUE;
+ return PL::EPSMap::obj_in_region(Regions::enclosing(I), reg);
}
@ String parameters.
@@ -684,7 +684,7 @@ void PL::EPSMap::new_map_hint_sentence(int pass, parse_node *p) {
break;
case INSTANCE_MAP_SCOPE:
if ((Spatial::object_is_a_room(<>)) ||
- (PL::Regions::object_is_a_region(<>)))
+ (Regions::object_is_a_region(<>)))
scope_I = <>;
if (scope_I) {
LOGIF(SPATIAL_MAP, "Setting for object $O\n", scope_I);
diff --git a/inform7/if-module/Chapter 3/HTML Map.w b/inform7/if-module/Chapter 3/HTML Map.w
index 41b72aba2..3dc65ca5f 100644
--- a/inform7/if-module/Chapter 3/HTML Map.w
+++ b/inform7/if-module/Chapter 3/HTML Map.w
@@ -433,7 +433,7 @@ from each other.)
instance *R;
LOOP_OVER_ROOMS(R)
if (MAP_DATA(R)->world_index_colour == NULL) {
- instance *reg = PL::Regions::enclosing(R);
+ instance *reg = Regions::enclosing(R);
if (reg)
MAP_DATA(R)->world_index_colour = MAP_DATA(reg)->world_index_colour;
else
@@ -1045,7 +1045,7 @@ int PL::HTMLMap::add_key_for(OUTPUT_STREAM, instance *reg) {
int count = 0;
instance *R;
LOOP_OVER_ROOMS(R) {
- if (PL::Regions::enclosing(R) == reg) {
+ if (Regions::enclosing(R) == reg) {
if (count++ == 0) {
@;
} else {
diff --git a/inform7/if-module/Chapter 3/Regions.w b/inform7/if-module/Chapter 3/Regions.w
index d8cec8472..3244a1cbf 100644
--- a/inform7/if-module/Chapter 3/Regions.w
+++ b/inform7/if-module/Chapter 3/Regions.w
@@ -1,107 +1,73 @@
-[PL::Regions::] Regions.
+[Regions::] Regions.
A plugin providing support for grouping rooms together into named
and nestable regions.
-@ The relation "R in S" behaves so differently for regions that we need to
-define it separately, even though there's no difference in English syntax. So:
-
-= (early code)
-binary_predicate *R_regional_containment = NULL;
-
@ "Region" is in fact one of the four top-level kinds in the standard I7
-hierarchy, alongside thing, room and direction.
-
-= (early code)
-kind *K_region = NULL;
-inference_subject *infs_region = NULL;
-property *P_map_region = NULL; /* a value property giving the region of a room */
-property *P_regional_found_in = NULL; /* an I6-only property used for implementation */
-
-@ Every inference subject contains a pointer to its own unique copy of the
-following minimal structure, though it will only be relevant for instances of
-"room":
-
-@d REGIONS_DATA(I) PLUGIN_DATA_ON_INSTANCE(regions, I)
+world model, alongside thing, room and direction. What makes it complicated
+is that it can contain rooms and other regions, but that this form of
+containment is implemented differently from spatial containment: as a
+result, a new "regional containment" relation is needed.
=
-typedef struct regions_data {
- struct instance *in_region; /* smallest region containing me (rooms only) */
- struct parse_node *in_region_set_at; /* where this is decided */
- struct inter_name *in_region_iname; /* for testing regional containment found-ins */
- CLASS_DEFINITION
-} regions_data;
-
-@h Initialising.
-
-=
-void PL::Regions::start(void) {
- PluginManager::plug(CREATE_INFERENCE_SUBJECTS_PLUG, PL::Regions::create_inference_subjects);
- PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, PL::Regions::regions_new_base_kind_notify);
- PluginManager::plug(SET_SUBKIND_NOTIFY_PLUG, PL::Regions::regions_set_subkind_notify);
- PluginManager::plug(NEW_SUBJECT_NOTIFY_PLUG, PL::Regions::regions_new_subject_notify);
- PluginManager::plug(NEW_PROPERTY_NOTIFY_PLUG, PL::Regions::regions_new_property_notify);
- PluginManager::plug(COMPLETE_MODEL_PLUG, PL::Regions::regions_complete_model);
- PluginManager::plug(MORE_SPECIFIC_PLUG, PL::Regions::regions_more_specific);
- PluginManager::plug(INTERVENE_IN_ASSERTION_PLUG, PL::Regions::regions_intervene_in_assertion);
- PluginManager::plug(NAME_TO_EARLY_INFS_PLUG, PL::Regions::regions_name_to_early_infs);
- PluginManager::plug(ADD_TO_WORLD_INDEX_PLUG, PL::Regions::regions_add_to_World_index);
- PluginManager::plug(PRODUCTION_LINE_PLUG, PL::Regions::production_line);
+void Regions::start(void) {
+ PluginManager::plug(CREATE_INFERENCE_SUBJECTS_PLUG, Regions::create_inference_subjects);
+ PluginManager::plug(NEW_BASE_KIND_NOTIFY_PLUG, Regions::new_base_kind_notify);
+ PluginManager::plug(SET_SUBKIND_NOTIFY_PLUG, Regions::set_subkind_notify);
+ PluginManager::plug(NEW_SUBJECT_NOTIFY_PLUG, Regions::new_subject_notify);
+ PluginManager::plug(NEW_PROPERTY_NOTIFY_PLUG, Regions::new_property_notify);
+ PluginManager::plug(COMPLETE_MODEL_PLUG, Regions::complete_model);
+ PluginManager::plug(MORE_SPECIFIC_PLUG, Regions::more_specific);
+ PluginManager::plug(INTERVENE_IN_ASSERTION_PLUG, Regions::intervene_in_assertion);
+ PluginManager::plug(NAME_TO_EARLY_INFS_PLUG, Regions::name_to_early_infs);
+ PluginManager::plug(ADD_TO_WORLD_INDEX_PLUG, IXRegions::add_to_World_index);
+ PluginManager::plug(PRODUCTION_LINE_PLUG, Regions::production_line);
}
-int PL::Regions::production_line(int stage, int debugging,
+int Regions::production_line(int stage, int debugging,
stopwatch_timer *sequence_timer) {
if (stage == INTER1_CSEQ) {
- BENCH(PL::Regions::write_regional_found_in_routines);
+ BENCH(RTRegions::write_found_in_functions);
}
return FALSE;
}
-int PL::Regions::create_inference_subjects(void) {
- infs_region = InferenceSubjects::new_fundamental(global_constants, "region(early)");
- return FALSE;
-}
+@ There is one kind of interest: "region", of course. It is recognised by the English
+name in the Standard Rules. (So there is no need to translate this to other languages.)
-regions_data *PL::Regions::new_data(inference_subject *subj) {
- regions_data *rd = CREATE(regions_data);
- rd->in_region = NULL;
- rd->in_region_set_at = NULL;
- rd->in_region_iname = NULL;
- return rd;
-}
+= (early code)
+kind *K_region = NULL;
+inference_subject *infs_region = NULL;
-inter_name *PL::Regions::found_in_iname(instance *I) {
- if (REGIONS_DATA(I)->in_region_iname == NULL)
- REGIONS_DATA(I)->in_region_iname = Hierarchy::make_iname_in(REGION_FOUND_IN_FN_HL, RTInstances::package(I));
- return REGIONS_DATA(I)->in_region_iname;
-}
-
-@h Kinds.
-This a kind name to do with regions which Inform provides special support
-for; it recognises the English name when defined by the Standard Rules. (So
-there is no need to translate this to other languages.)
-
-=
+@ =
::=
region
@ =
-int PL::Regions::regions_new_base_kind_notify(kind *new_base, char *text_stream, wording W) {
+int Regions::new_base_kind_notify(kind *new_base, char *text_stream, wording W) {
if ((W)) {
K_region = new_base; return TRUE;
}
return FALSE;
}
-int PL::Regions::regions_new_subject_notify(inference_subject *subj) {
- ATTACH_PLUGIN_DATA_TO_SUBJECT(regions, subj, PL::Regions::new_data(subj));
+@ As with the handling of the main spatial kinds, we need a placeholder for the
+"region" subject until |K_region| is ready to be created.
+
+=
+int Regions::create_inference_subjects(void) {
+ infs_region = InferenceSubjects::new_fundamental(global_constants, "region(early)");
+ return FALSE;
+}
+int Regions::name_to_early_infs(wording W, inference_subject **infs) {
+ if (((W)) && (K_region == NULL)) *infs = infs_region;
return FALSE;
}
-@ Region needs to be an abstract object, not a thing or a room, so:
+@ Region is not allowed to be made a subkind of anything else:
=
-int PL::Regions::regions_set_subkind_notify(kind *sub, kind *super) {
+int Regions::set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_region) && (super != K_object)) {
if (problem_count == 0)
StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_RegionAdrift),
@@ -114,10 +80,17 @@ int PL::Regions::regions_set_subkind_notify(kind *sub, kind *super) {
return FALSE;
}
-@ =
-int PL::Regions::object_is_a_region(instance *I) {
- if ((K_region) && (I) && (Instances::of_kind(I, K_region))) return TRUE;
- return FALSE;
+@ Note that because we use regular |parentage_inf| inferences to remember
+that one region is inside another, it follows that the progenitor of a
+region is either the next broadest region containing it, or else |NULL|.
+
+=
+instance *Regions::enclosing(instance *reg) {
+ instance *P = NULL;
+ if (Spatial::object_is_a_room(reg)) P = REGIONS_DATA(reg)->in_region;
+ if (Regions::object_is_a_region(reg)) P = Spatial::progenitor(reg);
+ if (Regions::object_is_a_region(P) == FALSE) return NULL;
+ return P;
}
@ Rooms are always more specific than regions; if region X is within
@@ -126,7 +99,7 @@ equally specific. (This is used in sorting rules by the specificity of their
domains.)
=
-int PL::Regions::regions_more_specific(instance *I1, instance *I2) {
+int Regions::more_specific(instance *I1, instance *I2) {
int r1 = Instances::of_kind(I1, K_room);
int r2 = Instances::of_kind(I2, K_room);
int reg1 = Instances::of_kind(I1, K_region);
@@ -140,8 +113,39 @@ int PL::Regions::regions_more_specific(instance *I1, instance *I2) {
return 0;
}
-@h Properties.
-This is a property name to do with regions which Inform provides special
+@ Detecting regions is easy. Note that if this plugin is inactive then
+|K_region| will be null, and this will always return false.
+
+=
+int Regions::object_is_a_region(instance *I) {
+ if ((K_region) && (I) && (Instances::of_kind(I, K_region))) return TRUE;
+ return FALSE;
+}
+
+@ Every inference subject contains a pointer to its own unique copy of the
+following minimal structure, though it will only be relevant for instances of
+"region":
+
+@d REGIONS_DATA(I) PLUGIN_DATA_ON_INSTANCE(regions, I)
+
+=
+typedef struct regions_data {
+ struct instance *in_region; /* smallest region containing me (rooms only) */
+ struct parse_node *in_region_set_at; /* where this is decided */
+ struct inter_name *in_region_iname; /* for testing regional containment found-ins */
+ CLASS_DEFINITION
+} regions_data;
+
+int Regions::new_subject_notify(inference_subject *subj) {
+ regions_data *rd = CREATE(regions_data);
+ rd->in_region = NULL;
+ rd->in_region_set_at = NULL;
+ rd->in_region_iname = NULL;
+ ATTACH_PLUGIN_DATA_TO_SUBJECT(regions, subj, rd);
+ return FALSE;
+}
+
+@ This is a property name to do with regions which Inform provides special
support for; it recognises the English name when it is defined by the
Standard Rules. (So there is no need to translate this to other languages.)
@@ -150,18 +154,18 @@ Standard Rules. (So there is no need to translate this to other languages.)
map region
@ =
-int PL::Regions::regions_new_property_notify(property *prn) {
+property *P_map_region = NULL; /* a value property giving the region of a room */
+int Regions::new_property_notify(property *prn) {
if ((prn->name))
P_map_region = prn;
return FALSE;
}
-@h Assertions.
-The following doesn't really intervene at all: it simply produces two problem
+@ The following doesn't really intervene at all: it simply produces two problem
messages which would have been less helpful if core Inform had produced them.
=
-int PL::Regions::regions_intervene_in_assertion(parse_node *px, parse_node *py) {
+int Regions::intervene_in_assertion(parse_node *px, parse_node *py) {
if ((Node::get_type(px) == PROPER_NOUN_NT) &&
(Node::get_type(py) == COMMON_NOUN_NT)) {
inference_subject *left_subject = Node::get_subject(px);
@@ -199,110 +203,10 @@ int PL::Regions::regions_intervene_in_assertion(parse_node *px, parse_node *py)
return FALSE;
}
-@h Relations.
+@ Model completion:
=
-int PL::Regions::regions_name_to_early_infs(wording W, inference_subject **infs) {
- if (((W)) && (K_region == NULL)) *infs = infs_region;
- return FALSE;
-}
-
-@ =
-void PL::Regions::create_relations(void) {
- R_regional_containment =
- BinaryPredicates::make_pair(spatial_bp_family,
- BPTerms::new(infs_region),
- BPTerms::new(KindSubjects::from_kind(K_object)),
- I"region-contains", I"in-region",
- NULL, Calculus::Schemas::new("TestRegionalContainment(*2,*1)"),
- PreformUtilities::wording(,
- REGIONAL_CONTAINMENT_RELATION_NAME));
- BinaryPredicates::set_index_details(R_regional_containment, NULL, "room/region");
-}
-
-@ We intervene only in limited cases: X contains Y, X regionally contains Y,
-or X incorporates Y; and only when X is a region. (This of course only
-applies to the built-in spatial relationships; regions are entirely free
-to participate in nonspatial relations.)
-
-=
-int PL::Regions::assert_relations(binary_predicate *relation,
- instance *I0, instance *I1) {
- int I0_is_region = FALSE;
- if (Instances::of_kind(I0, K_region)) I0_is_region = TRUE;
- int I1_is_region = FALSE;
- if (Instances::of_kind(I1, K_region)) I1_is_region = TRUE;
-
- if (I0_is_region) {
- if ((relation == R_incorporation) ||
- (relation == R_containment) ||
- (relation == R_regional_containment)) {
- @;
- if (I1_is_region) @
- else @ ;
- } else {
- StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_RegionRelation),
- "regions can only contain rooms",
- "and have no other relationships.");
- }
- return TRUE;
- } else if (I1_is_region) {
- if ((relation == R_incorporation) ||
- (relation == R_containment) ||
- (relation == R_regional_containment)) {
- StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_RegionRelation2),
- "regions can only be contained in other regions",
- "and not for example in rooms.");
- }
- }
-
- return FALSE;
-}
-
-@ =
- if ((REGIONS_DATA(I1)->in_region) &&
- (REGIONS_DATA(I1)->in_region != I0)) {
- StandardProblems::sentence_problem(Task::syntax_tree(), _p_(PM_RegionInTwoRegions),
- "each region can only be declared to be inside a single "
- "other region",
- "since although regions can be placed inside each other, "
- "they are not permitted to overlap.");
- return TRUE;
- }
- REGIONS_DATA(I1)->in_region = I0;
- REGIONS_DATA(I1)->in_region_set_at = current_sentence;
-
-@ =
- inference_subject *inner = Instances::as_subject(I1);
- inference_subject *outer = Instances::as_subject(I0);
- SpatialInferences::infer_parentage(inner, CERTAIN_CE, outer);
-
-@ Anything in or part of a region is necessarily a room, if it isn't known
-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);
- PropertyInferences::draw(rm, P_map_region, spec);
-
-@ Note that because we use regular |PARENTAGE_INF| inferences to remember
-that one region is inside another, it follows that the progenitor of a
-region is either the next broadest region containing it, or else |NULL|.
-
-=
-instance *PL::Regions::enclosing(instance *reg) {
- instance *P = NULL;
- if (Spatial::object_is_a_room(reg)) P = REGIONS_DATA(reg)->in_region;
- if (PL::Regions::object_is_a_region(reg)) P = Spatial::progenitor(reg);
- if (PL::Regions::object_is_a_region(P) == FALSE) return NULL;
- return P;
-}
-
-@h Model completion.
-
-=
-int PL::Regions::regions_complete_model(int stage) {
+int Regions::complete_model(int stage) {
if (stage == WORLD_STAGE_II) @;
if (stage == WORLD_STAGE_III) @;
return FALSE;
@@ -329,45 +233,101 @@ int PL::Regions::regions_complete_model(int stage) {
}
@ =
- P_regional_found_in = ValueProperties::new_nameless(
+ property *P_regional_found_in = ValueProperties::new_nameless(
I"regional_found_in", K_text);
instance *I;
LOOP_OVER_INSTANCES(I, K_object)
if (Instances::of_kind(I, K_region)) {
- inter_name *iname = PL::Regions::found_in_iname(I);
+ inter_name *iname = RTRegions::found_in_iname(I);
ValueProperties::assert(P_regional_found_in, Instances::as_subject(I),
Rvalues::from_iname(iname), CERTAIN_CE);
}
-@ =
-void PL::Regions::write_regional_found_in_routines(void) {
- instance *I;
- LOOP_OVER_INSTANCES(I, K_object)
- if (Instances::of_kind(I, K_region)) {
- inter_name *iname = PL::Regions::found_in_iname(I);
- packaging_state save = Routines::begin(iname);
- Produce::inv_primitive(Emit::tree(), IF_BIP);
- Produce::down(Emit::tree());
- Produce::inv_call_iname(Emit::tree(), Hierarchy::find(TESTREGIONALCONTAINMENT_HL));
- Produce::down(Emit::tree());
- Produce::val_iname(Emit::tree(), K_object, Hierarchy::find(LOCATION_HL));
- Produce::val_iname(Emit::tree(), K_object, RTInstances::iname(I));
- Produce::up(Emit::tree());
- Produce::code(Emit::tree());
- Produce::down(Emit::tree());
- Produce::rtrue(Emit::tree());
- Produce::up(Emit::tree());
- Produce::up(Emit::tree());
- Produce::rfalse(Emit::tree());
- Routines::end(save);
- }
-}
+@ The relation "R in S" behaves so differently for regions that we need to
+define it separately, even though there's no difference in English syntax. So:
+
+= (early code)
+binary_predicate *R_regional_containment = NULL;
@ =
-int PL::Regions::regions_add_to_World_index(OUTPUT_STREAM, instance *O) {
- if ((O) && (Instances::of_kind(O, K_room))) {
- instance *R = PL::Regions::enclosing(O);
- if (R) PL::HTMLMap::colour_chip(OUT, O, R, REGIONS_DATA(O)->in_region_set_at);
+void Regions::create_relations(void) {
+ R_regional_containment =
+ BinaryPredicates::make_pair(spatial_bp_family,
+ BPTerms::new(infs_region),
+ BPTerms::new(KindSubjects::from_kind(K_object)),
+ I"region-contains", I"in-region",
+ NULL, Calculus::Schemas::new("TestRegionalContainment(*2,*1)"),
+ PreformUtilities::wording(,
+ REGIONAL_CONTAINMENT_RELATION_NAME));
+ BinaryPredicates::set_index_details(R_regional_containment, NULL, "room/region");
+}
+
+@ We intervene only in limited cases: X contains Y, X regionally contains Y,
+or X incorporates Y; and only when X is a region. (This of course only
+applies to the built-in spatial relationships; regions are entirely free
+to participate in nonspatial relations.)
+
+=
+int Regions::assert_relations(binary_predicate *relation,
+ instance *I0, instance *I1) {
+ int I0_is_region = FALSE;
+ if (Instances::of_kind(I0, K_region)) I0_is_region = TRUE;
+ int I1_is_region = FALSE;
+ if (Instances::of_kind(I1, K_region)) I1_is_region = TRUE;
+
+ if (I0_is_region) {
+ if ((relation == R_incorporation) ||
+ (relation == R_containment) ||
+ (relation == R_regional_containment)) {
+ @;
+ if (I1_is_region) @
+ else @ ;
+ } else {
+ StandardProblems::sentence_problem(Task::syntax_tree(),
+ _p_(PM_RegionRelation),
+ "regions can only contain rooms",
+ "and have no other relationships.");
+ }
+ return TRUE;
+ } else if (I1_is_region) {
+ if ((relation == R_incorporation) ||
+ (relation == R_containment) ||
+ (relation == R_regional_containment)) {
+ StandardProblems::sentence_problem(Task::syntax_tree(),
+ _p_(PM_RegionRelation2),
+ "regions can only be contained in other regions",
+ "and not for example in rooms.");
+ }
}
+
return FALSE;
}
+
+@ =
+ if ((REGIONS_DATA(I1)->in_region) &&
+ (REGIONS_DATA(I1)->in_region != I0)) {
+ StandardProblems::sentence_problem(Task::syntax_tree(),
+ _p_(PM_RegionInTwoRegions),
+ "each region can only be declared to be inside a single "
+ "other region",
+ "since although regions can be placed inside each other, "
+ "they are not permitted to overlap.");
+ return TRUE;
+ }
+ REGIONS_DATA(I1)->in_region = I0;
+ REGIONS_DATA(I1)->in_region_set_at = current_sentence;
+
+@ =
+ inference_subject *inner = Instances::as_subject(I1);
+ inference_subject *outer = Instances::as_subject(I0);
+ SpatialInferences::infer_parentage(inner, CERTAIN_CE, outer);
+
+@ Anything in or part of a region is necessarily a room, if it isn't known
+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);
+ PropertyInferences::draw(rm, P_map_region, spec);
+
diff --git a/inform7/if-module/Chapter 3/Spatial Map.w b/inform7/if-module/Chapter 3/Spatial Map.w
index e6715bef7..da1c0f412 100644
--- a/inform7/if-module/Chapter 3/Spatial Map.w
+++ b/inform7/if-module/Chapter 3/Spatial Map.w
@@ -2498,8 +2498,8 @@ int PL::SpatialMap::compare_components(const void *ent1, const void *ent2) {
instance *R1 = mc1->first_room_in_submap;
instance *R2 = mc2->first_room_in_submap;
if ((R1) && (R2)) { /* which should always happen, but just in case of an error */
- instance *reg1 = PL::Regions::enclosing(R1);
- instance *reg2 = PL::Regions::enclosing(R2);
+ instance *reg1 = Regions::enclosing(R1);
+ instance *reg2 = Regions::enclosing(R2);
if ((reg1) && (reg2 == NULL)) return -1;
if ((reg1 == NULL) && (reg2)) return 1;
if (reg1) {
@@ -2622,12 +2622,12 @@ running time in check.
if (sub->bounds.population == 1) {
instance *R = sub->first_room_in_submap;
if (R) { /* which should always happen, but just in case of an error */
- instance *reg = PL::Regions::enclosing(R);
+ instance *reg = Regions::enclosing(R);
if (reg) {
instance *S, *closest_S = NULL;
int closest = 0;
LOOP_OVER_ROOMS(S)
- if ((S != R) && (PL::Regions::enclosing(S) == reg))
+ if ((S != R) && (Regions::enclosing(S) == reg))
if ((posnd == FALSE) || (MAP_DATA(S)->submap->positioned)) {
int diff = 2*(R->allocation_id - S->allocation_id);
if (diff < 0) diff = 1-diff;
@@ -2759,7 +2759,7 @@ void PL::SpatialMap::log_precis_of_map(void) {
if (Instances::of_kind(R, K_room)) {
wording RW = Instances::get_name(R, FALSE);
LOG("%+W is a room.\n", RW);
- instance *reg = PL::Regions::enclosing(R);
+ instance *reg = Regions::enclosing(R);
if (reg) {
wording RGW = Instances::get_name(reg, FALSE);
if (MAP_DATA(reg)->zone == 1) {
diff --git a/inform7/if-module/Chapter 3/Spatial Model.w b/inform7/if-module/Chapter 3/Spatial Model.w
index 865a4bbaa..eb77542a5 100644
--- a/inform7/if-module/Chapter 3/Spatial Model.w
+++ b/inform7/if-module/Chapter 3/Spatial Model.w
@@ -703,7 +703,7 @@ int Spatial::spatial_stage_II(void) {
if ((Spatial::progenitor(I)) &&
(Instances::of_kind(I, K_thing) == FALSE) &&
(Instances::of_kind(I, K_room) == FALSE) &&
- (PL::Regions::object_is_a_region(I) == FALSE)) {
+ (Regions::object_is_a_region(I) == FALSE)) {
Problems::quote_source(1, Instances::get_creating_sentence(I));
Problems::quote_object(2, I);
Problems::quote_object(3, Spatial::progenitor(I));
diff --git a/inform7/if-module/Chapter 3/Spatial Relations.w b/inform7/if-module/Chapter 3/Spatial Relations.w
index 9c2a311e7..2683b5f9e 100644
--- a/inform7/if-module/Chapter 3/Spatial Relations.w
+++ b/inform7/if-module/Chapter 3/Spatial Relations.w
@@ -36,7 +36,7 @@ void SpatialRelations::stock(bp_family *self, int n) {
@;
@;
PL::MapDirections::create_relations();
- PL::Regions::create_relations();
+ Regions::create_relations();
}
}
@@ -207,7 +207,7 @@ way which isn't symmetrical between the two, and this way round is cleanest.
@ =
if (Backdrops::assert_relations(bp, I0, I1)) return TRUE;
if (PL::MapDirections::assert_relations(bp, I0, I1)) return TRUE;
- if (PL::Regions::assert_relations(bp, I0, I1)) return TRUE;
+ if (Regions::assert_relations(bp, I0, I1)) return TRUE;
@ This is the point at which non-assertable relations are thrown out.
diff --git a/inform7/index-module/Chapter 2/Index Physical World.w b/inform7/index-module/Chapter 2/Index Physical World.w
index 98c93c358..e9b72d080 100644
--- a/inform7/index-module/Chapter 2/Index Physical World.w
+++ b/inform7/index-module/Chapter 2/Index Physical World.w
@@ -72,13 +72,13 @@ void Data::Objects::page_World(OUTPUT_STREAM) {
@ =
instance *reg;
LOOP_OVER_INSTANCES(reg, K_object)
- if (PL::Regions::object_is_a_region(reg)) {
+ if (Regions::object_is_a_region(reg)) {
int subheaded = FALSE;
IXInstances::increment_indexing_count(reg);
instance *rm;
LOOP_OVER_INSTANCES(rm, K_object)
if ((Spatial::object_is_a_room(rm)) &&
- (PL::Regions::enclosing(rm) == reg)) {
+ (Regions::enclosing(rm) == reg)) {
if (subheaded == FALSE) {
@;
@;
@@ -93,7 +93,7 @@ void Data::Objects::page_World(OUTPUT_STREAM) {
@ =
WRITE("The %+W region", Instances::get_name(reg, FALSE));
- instance *within = PL::Regions::enclosing(reg);
+ instance *within = Regions::enclosing(reg);
if (within) WRITE(" within the %+W region", Instances::get_name(within, FALSE));
WRITE(" ");
diff --git a/inform7/index-module/Chapter 3/Regions.w b/inform7/index-module/Chapter 3/Regions.w
new file mode 100644
index 000000000..edfbaf668
--- /dev/null
+++ b/inform7/index-module/Chapter 3/Regions.w
@@ -0,0 +1,14 @@
+[IXRegions::] Regions.
+
+Indexing the player's initial position.
+
+@
+
+=
+int IXRegions::add_to_World_index(OUTPUT_STREAM, instance *O) {
+ if ((O) && (Instances::of_kind(O, K_room))) {
+ instance *R = Regions::enclosing(O);
+ if (R) PL::HTMLMap::colour_chip(OUT, O, R, REGIONS_DATA(O)->in_region_set_at);
+ }
+ return FALSE;
+}
diff --git a/inform7/index-module/Contents.w b/inform7/index-module/Contents.w
index 0d54f7b20..409d23fa6 100644
--- a/inform7/index-module/Contents.w
+++ b/inform7/index-module/Contents.w
@@ -30,3 +30,4 @@ Chapter 3: Indexing for Plugins
Spatial
The Player
Backdrops
+ Regions
diff --git a/inform7/runtime-module/Chapter 5/Regions.w b/inform7/runtime-module/Chapter 5/Regions.w
new file mode 100644
index 000000000..d02a43ee9
--- /dev/null
+++ b/inform7/runtime-module/Chapter 5/Regions.w
@@ -0,0 +1,37 @@
+[RTRegions::] Regions.
+
+@
+
+=
+inter_name *RTRegions::found_in_iname(instance *I) {
+ if (REGIONS_DATA(I)->in_region_iname == NULL)
+ REGIONS_DATA(I)->in_region_iname =
+ Hierarchy::make_iname_in(REGION_FOUND_IN_FN_HL, RTInstances::package(I));
+ return REGIONS_DATA(I)->in_region_iname;
+}
+
+@ =
+void RTRegions::write_found_in_functions(void) {
+ instance *I;
+ LOOP_OVER_INSTANCES(I, K_object)
+ if (Instances::of_kind(I, K_region)) {
+ inter_name *iname = RTRegions::found_in_iname(I);
+ packaging_state save = Routines::begin(iname);
+ Produce::inv_primitive(Emit::tree(), IF_BIP);
+ Produce::down(Emit::tree());
+ Produce::inv_call_iname(Emit::tree(),
+ Hierarchy::find(TESTREGIONALCONTAINMENT_HL));
+ Produce::down(Emit::tree());
+ Produce::val_iname(Emit::tree(), K_object, Hierarchy::find(LOCATION_HL));
+ Produce::val_iname(Emit::tree(), K_object, RTInstances::iname(I));
+ Produce::up(Emit::tree());
+ Produce::code(Emit::tree());
+ Produce::down(Emit::tree());
+ Produce::rtrue(Emit::tree());
+ Produce::up(Emit::tree());
+ Produce::up(Emit::tree());
+ Produce::rfalse(Emit::tree());
+ Routines::end(save);
+ }
+}
+
diff --git a/inform7/runtime-module/Contents.w b/inform7/runtime-module/Contents.w
index 01cb0abc3..038289604 100644
--- a/inform7/runtime-module/Contents.w
+++ b/inform7/runtime-module/Contents.w
@@ -68,3 +68,4 @@ Chapter 5: Plugin Support
Spatial
The Player
Backdrops
+ Regions