skip to main content
Debugging and Analysis : RPL Debugging and Analysis : Types of RPL Debugging and Analysis
Types of RPL Debugging and Analysis
When building and executing RPL policy, there are three situations when debugging and analysis is required:
• When you encounter when building or validating RPL logic
• When you encounter an error when executing RPL logic
• When RPL logic produces the incorrect result or you wish to understand the RPL logic in more detail
Within this section is an overview of each situation. Then, in the remainder of the document, are the tools that can be used for debugging including the RPL Debugger, Diagnostics, Run Analysis, and RPL Analysis.
Building and Validation Errors
There are several errors (non-evaluation errors) which may be encountered when building or validating RPL sets. These messages do not immediately affect a model run, but will likely result in a run failure if not addressed. Messages may appear in the Diagnostics Output Window or in an error notification window which appears at the time of the error.
Errors When Building RPL Expressions
When an unspecified expression is filled in by entering text into its text field, the entry is parsed to ensure that it meets the requirements of the desired type. If the entry is not valid, a diagnostic message is generated. For example, entering @“t” into an unspecified <numeric expr> would generate the following message shown in Figure 4.1 and revert the expression to its prior, unspecified, state.
Figure 4.1   
Another kind of parsing error can occur when the correct expression data type is improperly entered. For example, typing @“Octobre” into an unspecified <datetime expr> would generate the message shown in Figure 4.2 and revert the expression to its prior, unspecified, state.
Figure 4.2   
In both of these cases, the entered expression was incorrect. Examination of the expression and the diagnostics message should point out the flaw.
Errors During RPL Set Validation
RPL sets are validated at several stages prior to a run. Validation ensures that a RPL set meets a minimum level of accuracy for its intended use. There are different levels of validity required for different stages of RPL set opening, editing, and running. The validity levels are as follows.
Hopeless
• A hopeless RPL set is one which cannot be read. This can occur if the RPL set file has been incorrectly modified with a text editor or if the file has been corrupted. In these cases, the parser cannot even read the RPL set to display it in the RPL set editor. If at any time, a RPL set is corrupted such that it cannot be opened, please contact RiverWare technical support at: riverware-support@colorado.edu
Printable
A printable RPL set is one which can be read by the parser and displayed in the RPL set editor. This means that the expressions are syntactically correct, even though some may evaluate to data types which are inconsistent with their use in an outer scope. This level of validation is most frequently caused by an ambiguous expression being saved in the RPL set. Ambiguous expressions are expressions whose operator precedence allows more than one interpretation. Ambiguous expressions can be fixed by placing parentheses around the appropriate sub-expressions. A button for adding parentheses can be found in the rule palette. When RPL sets which only pass the printable validation are opened, errors are printed to the Diagnostics Output Window. The errors may then be fixed through the RPL set editor.
Consistent
A consistent RPL set is one which is printable and whose expressions’ data types are consistent with each other. For example, a sub-expression of type NUMERIC exists where a NUMERIC expression is expected in a higher level expression. Some expressions may be unspecified if they are of the correct data type. The consistency of data types is determined for all types except LIST, whose member types cannot be fully determined until the expression is evaluated at run time. A consistent RPL set may not properly evaluate at run time, but it will not generate any errors when it is opened.
Evaluatable
An evaluatable RPL set is one which, as far as can be determined without actually evaluating it, could be successfully evaluated. This means that all of the previous validity levels have been satisfied. This also means that there cannot be any remaining unspecified expressions in the RPL set and that any object or slot references must map to an existing object or slot in the currently loaded model.
Given those definitions for the various results of validating a RPL set, the following actions can lead to validation errors.
Open RPL Set
When a RPL set is opened, its functions and blocks are parsed from the file and the set is validated to the printable level. The printable validation ensures that the RPL set can be displayed in the RPL set editor’s graphical user interface. RPL sets are also validated to the same level when they are saved to ensure that they can be reloaded at a later time. Some older RPL sets which contain critical errors, and corrupted RPL set files may fail to load. In these cases, the window shown in Figure 4.3 appears, indicating the location within the file where the error was detected.
Figure 4.3   
A message will also appear in the Diagnostics Output Window indicating that the “RPL set loading failed” and provide the path and name of the RPL set. The Diagnostics Output Window will display the line number in which the parsing error occurred. If this should occur, first verify that the file you are attempting to load is indeed a RPL set, then contact RiverWare technical support.
Load RPL Set or Validate RPL Set
When a RPL set is loaded by selecting the RPL Set Not Loaded button in the RPL set editor or Check Validity is selected from the RPL set menu, the RPL set is validated to the evaluatable level. This means that all of the rule and function expressions are syntactically correct, have consistent expression data types, are fully specified, and reference objects and slots which exist on the workspace. If any of these criteria are not met, the RPL set is not validated and it cannot be loaded into the model. In this case, a window appears indicating one of the two messages shown in Figure 4.4.
Figure 4.4   
Another message appears in the Diagnostics Output Window describing the validation errors. Loaded RPL sets are also validated to the evaluatable level when a run is begun. This is to validate any changes which were made to the RPL set since it was successfully loaded. If any errors are detected, the run is stopped, and the appropriate diagnostic messages are displayed.
Evaluation and Runtime Errors
Several types of errors can be generated when evaluating RPL expressions. Some errors stop the run execution immediately, while others cause the current block to end with an early termination, but do not stop the run. The approach to debugging these errors varies depending on the error type. The error types are:
Non-fatal RPL Evaluation Errors
These are errors which occur within the evaluation of a rule. Most often, these errors are produced when an engineering predefined function fails because it is attempting to model something physically impossible. These errors are often the result of the object state; i.e., the values in the object’s slots. It is entirely possible for an engineering predefined function to fail during one rule evaluation, then succeed during another. The result of the engineering predefined function is almost always related to the state of the object at the time that the function evaluates.
For example, attempting to solve for the ending elevation of a reservoir given a starting elevation and flows which would cause overtopping of the reservoir would generate this kind of error. Some predefined functions can also fail in this way if they are attempting to access missing data or attempting to access data with incorrect arguments. Attempting to lookup values which do not exist in a tableslot would also generate a non-fatal evaluation error.
When the Rule Processor encounters a non-fatal rule evaluation error, it cannot continue evaluating the rule and must terminate early. Since the rule does not complete, no slots are set in the model. All existing slot values and priorities are still correct, and it is not necessary to stop the run.
When a non-fatal evaluation error is encountered, the error message is posted to the Diagnostics Output Window and immediately aborts the RPL statement. The block’s dependencies are preserved, such that the block may be re-evaluated if any of its dependent slots change.
Example 4.1  Example:
Consider the following rule which attempts to set Pool Elevation such that a target Storage is met. The Target Storage() is computed in an internal function. The StorageToElevation() predefined function is used to convert this target Storage to a Pool Elevation.
Res.Pool Elevation [] = StorageToElevation( %”Res”, TargetStorage(), @”Current Timestep” )
If the TargetStorage() user function evaluated to a value of 15,000,000 acre-ft, and the ElevationVolumeTable of Res contains the following data.
Pool Elevation
Storage
895.00
0
920.00
811,000
.
.
.
.
.
.
1060.00
8,241,000
1085.00
10,233,000
1110.00
12,452,000
1135.00
14,920,000
The predefined function, StorageToElevation(), will do the following:
• Check the validity of the arguments:
– Res is an object on the workspace which contains an Elevation Volume Table.
– 15,000,000 [acre-ft] is a numeric value in the unit type of volume.
– @”Current Timestep” is a valid timestep of the current model run.
• Attempt to find 15,000,000 [acre-ft] in the Storage column of the table.
• Fail to find 15,000,000 [acre-ft] in the Storage column:
– Post an error to the Diagnostics Output Window.
– Notify the rule that the evaluation of the predefined function failed.
Note:  There is nothing wrong with the StorageToElevation() function itself. The arguments that were provided to it are hypothetically valid. It just happens that the Storage value is too large for the data in the table. This is not a RPL set configuration or logic error. It is possible that the same rule could execute at a later time and that the TargetStorage() function would solve for a Storage of 14,000,000 [acre-ft]. Then, the StorageToElevation() function would succeed.
When the rule is notified that the StorageToElevation() function has failed with a data error, it cannot finish evaluating. The rule is aborted because there is incomplete information to continue. Since the rule has not yet set any values in the model, the existing state of the model is still valid; it is based entirely on user input and assignments from successful rules. Since this failed rule has had no effect on the model, there is no need to stop the run. In addition, this rule’s dependencies have been registered so that it can be re-fired if any of its dependent slots change at a later time. If Res’ Storage or downstream demands were to change, this rule may re-fire and evaluate successfully.
Non-fatal RPL evaluation errors do not always indicate a problem with a RPL set. Although a red error message is displayed in the Diagnostics Output Window, the failure of the RPL expression may be a desired action. This may initially confuse users who are accustomed to seeing error messages only when the run has been aborted. Error messages which are generated for non-fatal rule evaluation errors are intended to give the modeler an indication of the failed functions even though the evaluation continues. These error messages should be investigated to determine whether the function failure really was desired.
Example 4.2  Example:
In the previous example, the rule was attempting to set Res’ Pool Elevation corresponding to a target storage. If the Pool Elevation is higher than the reservoir capacity, it would not be wise to set this value on the slot. This would not be a valid reservoir operation, and the ensuing dispatch would surely fail, aborting the run.
If this rule is part of a ruleset where the Pool Elevation or Outflow of Res may be set to meet several criteria, we may want the rule to fail. Consider the following ruleset:
Set Res Pool Elevation for Flood Control
Set Res Pool Elevation for Target Storage
Set Res Outflow for Surplus Conditions
Set Res Pool Elevation based on Guide Curve
If our Target Storage rule (#2) would result in a Pool Elevation which would overtop the reservoir, we may want to let the Surplus Conditions rule (#3) dictate the operation of the reservoir. Even though Rule #3 has a lower priority than Rule #2, we prefer its safe operation to Rule #2’s. By evaluating an engineering predefined function which will test the mass balance of the reservoir, we give Rule #2 a chance to fail before it sets any slots. Once Rule #2 fails with the non-fatal error, the Rule Processor fires Rule #3. The design of this ruleset ensures that an unrealistic operation will not be attempted and that the run will not be aborted.
When examining non-fatal error messages, keep in mind that the failing function does not know whether its failure is critical or not. In a simulation dispatching context, a failed Elevation Volume Table interpolation is critical because it means the physical limit of the reservoir has been exceeded. In a rule evaluation context, a failed Elevation Volume Table interpolation is not very critical because it only means that a what-if calculation has exceeded the physical limit. In both cases, the table interpolation error is posted as soon as it is encountered. In the simulation dispatch case, the controller should immediately stop the run. In the rule evaluation case, the Rule Processor only needs to abort this rule and can then fire the next rule on the agenda.
Fatal RPL Evaluation Errors
Fatal RPL evaluation errors immediately abort execution. Unlike non-fatal RPL evaluation errors, these errors indicate a major problem with the RPL logic. These errors also occur within the evaluation of a RPL logic. Unlike non-fatal RPL evaluation errors, however, these errors are not dependent on the state of the system; they cannot be fixed by having different values in slots. These errors may be caused by missing arguments, arguments of the wrong data type, inconsistent unit types, invalid slot configurations, and/or missing objects and slots. These errors require intervention by the user if the run is ever to succeed. When the Rule Processor encounters a fatal rule evaluation error, the rule is aborted, the error message is posted to the Diagnostics Output Window, and the run is immediately stopped.
Predefined Functions
The number of arguments and data types of arguments to predefined functions are fixed. Each function checks the validity of its arguments when it is evaluated. The argument requirements for each predefined function are listed in RPL Predefined Functions section of the RiverWare help. If incorrect arguments are supplied to a predefined function, or the function fails to evaluate for other reasons, it may cause a fatal error. In this case, a message is posted in the Diagnostics Output Window and the run is immediately aborted.
Example 4.3  Example:
The ListSubbasin() predefined function evaluates to a list of objects. The objects are the objects defined in the subbasin on the workspace. The function takes a single argument of type STRING. If the argument is not the name of an existing subbasin in the model, the function generates a fatal error.
Calling the function with a non-existent subbasin as below:
Print ListSubbasin ( “Main Stem of River” )
The following error message is generated:
Evaluation of the Print statement failed for the following reason(s):
ListSubbasin() is the sequence of function calls (possibly containing only one function) which ended in an unsuccessful function call.
The function call failed for the following reason: Argument one is not a Subbasin.
This occurred at the following location within the expression:
“ListSubbasin ( “Main Stem of River” )”.
Notice the structure of the error message. The first line indicates that the Print statement failed. The second and third lines indicate the reason the Print statement failed is that the evaluation of the ListSubbasin() function failed. The fourth line indicates that the function failed because the first argument is not a subbasin. The fifth and sixth lines indicate where in the rule the failed function call originated. Reading all of the error message is critical to understanding, and fixing, what went wrong.
Inconsistent Unit Types
The RPL processor automatically converts numeric values to the proper units for mathematical operations during RPL evaluation. As long as the unit type of a value is correct, its units can be converted without affecting the expression. If the dimensional analysis is incorrect, however, the RPL processor stops the run.
Example 4.4  Example:
The mathematical expressions below may be evaluated because the unit types of their elements are consistent.
Res.Outflow [] = 10 [cms] + 50 [cfs]
FLOW = FLOW + FLOW
Res.Storage [] = 50,000 [acre-ft/month] x 31 [day]
VOLUME = FLOW x TIME
The values of expression elements on the right-hand side are converted to a common base unit prior to evaluation. Likewise, the result of the right-hand side is converted into RiverWare standard units so that it may be assigned to the slot.
Example 4.5  Example:
The mathematical expressions below may not be evaluated because the unit types of their elements are inconsistent.
Res.Outflow [] = 10 [cms] + 50 [acre-ft]
FLOW = FLOW + VOLUME
Res.Pool Elevation [] = 50,000 [acre-ft/month] x 31 [day]
LENGTH = FLOW x TIME
These expressions would cause fatal rule evaluation errors, such as the one shown in Figure 4.5.
RPL unit type errors are only detected during evaluation.
Figure 4.5   
Inconsistent Data Types
RPL requires that an expression evaluating to a particular data type be present where that data type is expected. This is enforced during the building of RPL expressions by only enabling expressions of the correct type in the Palette and by generating a parse error if an incorrect expression is directly typed into the text field. The error message, previously discussed, would read, “The entered expression cannot replace the selected expression”.
Expressions of data type LIST are not verified during the building of RPL expressions. This is because a list may contain elements of any data type and because the number and type of list elements may change during the evaluation. As a result, inconsistent data types originating in lists will not be caught until the RPL expression or function is evaluated. These errors will stop evaluation immediately with an error.
Example 4.6  Example:
The following rule will not generate any errors when it is constructed. When the ruleset is validated, it will be deemed evaluatable.
PRINT { TRUE, 1“day” } < 0 > + @ “t”
When this rule is evaluated, however, it causes the run to abort with the following message:
Evaluation of the PRINT statement is invalid for the following reasons: The left operand of + must be able to evaluate to a numeric or date/time value, and this is not currently possible. The problem was encountered at the following location within the expression: TRUE + t.
Here again, the message indicates that the addition operation did not work, but the problem probably lies withing the list. Either access the next item in the list or change the 0th item to have a valid type.
Missing Objects or Slots
If an object or slot which is referenced in a RPL expression does not exist on the workspace when the RPL expression is evaluated, a fatal RPL evaluation is produced. This can occur when the slot or object name was improperly entered in the RPL expression, when a RPL set is being used with the wrong model, or when object or data object slot names were changed after the RPL expression was created.
Names of objects and slots in a RPL set must exactly match an object and/or slot name on the workspace, including capitalization, spaces, and any underscores. Missing object or slot errors can be minimized by always using the Object Selector and Slot Selector to specify objects and slots in RPL expressions. Typing object or slot names directly into an expression textfield is not recommended due to the possibility of a syntax error.
Example 4.7  Example:
The following rule will not generate any errors when it is constructed. When the ruleset is validated, it will be deemed evaluatable.
Reservoir.Outflow[] = Reservoir.Inflow[]
When this rule is evaluated, however, it causes the run to abort with the following message:
Evaluation of the right-hand side of the Assignment statement failed for the following reason(s):
Failed to locate slot “Resarvoir.Inflow” on the global workspace.
This occurred at the following location within the expression: $”Resarvoir.Inflow”.
Fatal Simulation Errors
These errors occur during the dispatching phase of a Rulebased Simulation run and only apply to Rulebased Simulation rulesets. These errors are produced when the controller priority and the priorities of slot values are such that objects cannot solve the model. These errors are usually caused by objects dispatching with an unintended dispatch method, excessive redispatching of an object, and/or an overdetermined multislot. When these occur, the Rulebased Simulation Controller cannot determine how to continue, and the run is aborted with an error.
Fatal Simulation errors are often the most complex errors to understand and debug. These errors occur during the simulation dispatching which takes place after a rule successfully sets a slot value. In order to simulate the effects of the new slot value, many objects may need to redispatch. The dispatch method with which each object redispatches is determined from the object’s slot priorities. Occasionally, the priorities of the slots are such that a unique dispatch method cannot be identified. When this happens, the object will attempt to redispatch with the same method as it dispatched with the last time. One of two error situations may result.
Junior and Senior Slot Priority Error
If the slot which was just set by a rule is solved for during this dispatch, the slot priority conflict will cause the run to abort with an error. The error often indicates:
Attempting to set senior slot (priority) with a junior priority (same priority).
Assignment attempted within the dispatch triggered by rule #same priority.
The object probably did not dispatch with the intended method.
When this error occurs, the rule at the indicated priority is usually to blame. Often, this rule has set a slot value at a priority which confuses the simulation into choosing the wrong dispatch method.
Example 4.8  Example:
Consider a Reach object called Rio. Rio’s Inflow may be determined by the release of an upstream reservoir or its Outflow may be determined by downstream demands or environmental considerations. Both may be specified as long as the slot’s priorities can be used to determine the preferred solution.
The ruleset used to control Rio is shown below:
1. Set Rio Inflow due to Minimum Upstream Reservoir Release
Rio.Inflow[] = IF ( Rio.Inflow[] < DataObj.MinResRelease[] ) THEN DataObj.MinResRelease[]
2. Set Rio Outflow for Maximum Fish Flow
Rio.Outflow[] = IF ( Rio.Outflow[] > DataObj.MaxFishFlow[] ) THEN DataObj.MaxFishFlow[]
3. Set Rio Outflow to Meet Downstream Demands
Rio.Outflow[] = DataObj.TotalDownstreamDemand[]
The Rulebased Simulation proceeds as follows:
1. Initially, no values are known, so Rio cannot dispatch.
2. Rule #3 fires and sets Rio.Outflow to meet demands.
3. Rio dispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = unknown
– Outflow = known at priority 3R
and solves for Inflow at controller priority 3
4. Rule #2 fires and sets Rio.Outflow for maximum fish flow (assuming the rule logic evaluates to TRUE). The rule can overwrite the existing priority 3R Outflow with the new priority 2R Outflow.
5. Rio redispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 3
– Outflow = known at priority 2R
and solves for Inflow at controller priority 2.
6. Rule #1 fires and sets Rio.Inflow for minimum upstream release (assuming the rule logic evaluates to TRUE). The rule can overwrite the existing priority 2 Inflow with the new priority 1R Inflow.
7. Rio redispatches with the Solve given Inflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 1R
– Outflow = known at priority 2R
and solves for Outflow at controller priority 1. This causes Rule #2 to go back on the agenda because of a new value for Outflow.
8. Rule #2 fires and sets Rio.Outflow for maximum fish flow. The rule can overwrite the existing priority 1 (“O” flag) Outflow with the new priority 2R Outflow.
9. Rio redispatches with the Solve given Inflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 1R
– Outflow = known at priority 2R
and solves for Outflow at controller priority 2, the last rule that set a slot. This was not the intended dispatch! Rule #2 just set Rio.Outflow. The effect of this rule should not be to solve for a new Rio.Outflow. When the dispatch attempts to overwrite Outflow at priority 2R with a new value at priority 2, an error is generated
The responsibility for the error, in this case, falls squarely on Rule #2. This rule should not be attempting to enforce a maximum fish flow when a higher priority minimum release rule is controlling the river. Unfortunately, Rule #2 does not know that Rule #1 is controlling the river. There are two solutions to this error.
Because the rules are acting on different slots, they cannot depend exclusively on priorities to determine the appropriate solution. If Rule #2 were attempting to set Rio.Inflow instead, the rule would fail gracefully during the rule execution. The existing priority 1R would prevent Rule #2 from overwriting the slot value. Of course, changing Rule #2 to set Inflow could now create a similar problem between Rule #2 and Rule #3.
The other solution is to make Rule #2 smarter. Rule #2 could check the Inflow of Rio to see if it is at a level corresponding to the minimum upstream release. If this is the case, Rule #2 could then decide not to return a value from its right-hand side. It would exit ineffectively. Another way to let Rule #2 know that Rule #1 is controlling the river is to have Rule #1 set a state flag on a custom slot in the model. State flags are slots whose values indicate the current state of the system, such as surplus, shortage, or minimum release. A state flag could be checked by Rule #2 to decide if it should change Rio’s Outflow.
Infinite Loop Dispatching Error
Another error situation which can result from incorrect dispatching is an infinite loop. This can occur between two objects which are both solving for the same slot. Each object successfully solves for a new value on the slot, overwriting the previous value. Each new slot assignment triggers the other object to redispatch, during which it also solves for a new value on the slot. This continues until the maximum iterations are reached on one of the objects’ slots or the modeler terminates the RiverWare session.
Example 4.9  Example
Consider two Reach objects called UpperRio and LowerRio and a Diversion called UpperRioDiversion. The diversion is attached to the UpperRio Reach and can divert an amount of flow equal to the amount it leaves in the UpperRio. There are also irrigation demands downstream of the LowerRio. The system usually solves from the bottom up; downstream demands are set on LowerRio Outflow, then the Diversion Request is set on the UpperRioDiversion. As in the previous example, UpperRio Inflow may be overwritten by a minimum release rule.
The ruleset used to control the Rios is as follows.
1. Set UpperRio Inflow due to Minimum Upstream Reservoir Release
UpperRio.Inflow[] = IF ( UpperRio.Inflow[] < DataObj.MinResRelease[] ) THEN DataObj.MinResRelease[]
2. Set UpperRioDiversion Not to Exceed UpperRio.Outflow
UpperRioDiversion.Diversion Request[] = MIN (DataObj.UpperRioDivRequest[], UpperRio.Outflow[])
3. Set LowerRio Outflow to Meet Downstream Demands
LowerRio.Outflow[] = DataObj.TotalDownstreamDemand[]
The Rulebased Simulation proceeds as follows:
1. Rule #3 fires and sets LowerRio.Outflow to meet demands.
2. LowerRio dispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = unknown
– Outflow = known at priority 3R
and solves for Inflow at controller priority 3. This propagates across the link to UpperRio.Outflow.
3. UpperRio dispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = unknown
– Outflow = known at priority 3
but cannot solve completely because the UpperRioDiversion is not yet known.
4. Rule #2 fires and sets the UpperRioDiversion Diversion Request equal to the UpperRio Outflow (assuming that the request in the Data Obj is very large).
5. UpperRioDiversion dispatches and sets the Diversion from UpperRio at controller priority 2. This propagates across the link to UpperRio.Diversion.
6. UpperRio redispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = unknown
– Outflow = known at priority 3
– Diversion = known at priority 2
and solves for UpperRio.Inflow at controller priority 2.
7. Rule #1 fires and sets UpperRio.Inflow for minimum upstream release (assuming the rule logic evaluates to TRUE). The rule can overwrite the existing priority 2 Inflow with the new priority 1R Inflow.
8. UpperRio redispatches with the Solve given Inflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 1R
– Outflow = known at priority 3
– Diversion = known at priority 2
and solves for UpperRio.Outflow at controller priority 1. This puts Rule #2 back on the Agenda.
9. LowerRio redispatches with the Solve given Inflow, No Routing dispatch method based on these priorities
– Inflow = known at priority 1
– Outflow = known at priority 3R
and solves for Outflow at controller priority 1.
Now the stage is set for the error to take over.
10. Rule #2 fires and resets the UpperRioDiversion Diversion Request equal to the new UpperRio Outflow (assuming, again, that the request in the Data Obj is very large). The rule can overwrite the existing priority 2R Diversion Request with a new priority 2R Diversion Request.
11. UpperRio redispatches with the Solve given Inflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 1R
– Outflow = known at priority 1
– Diversion = known at priority 2
and solves for a new UpperRio.Outflow at controller priority 2. The dispatch can overwrite the existing priority 1 Outflow with a new priority 2 Outflow. This value propagates across the link to LowerRio’s Inflow. This also causes Rule #2 to be put back on the Agenda.
12. LowerRio redispatches with the Solve given Outflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 2
– Outflow = known at priority 1
and solves for a new Inflow at controller priority 2. This propagates across the link to UpperRio.Outflow.
13. UpperRio redispatches again with the Solve given Inflow, No Routing dispatch method based on these priorities:
– Inflow = known at priority 1R
– Outflow = known at priority 2
– Diversion = known at priority 2
and solves for a new UpperRio.Outflow at controller priority 2. This value propagates across the link to LowerRio’s Inflow.
14. The two Rios continue redispatching with the wrong dispatch methods and overwriting the results of each other’s solutions.
Slot maximum iteration checking is turned on by default and cannot be turned off when performing Rulebased Simulation, though the number of maximum iterations can be changed by the user. This iteration default can be viewed as a dimmed box for Check Iterations in the Rulebased Simulation Run Parameters dialog. From the View menu of the Run Control dialog, select Rulebased Simulation Run Parameters... to open the dialog. Within this dialog, the user can change the number of maximum iterations (the default number of maximum iterations is 40). For more complex models, the user may be required to increase the number of maximum iterations.
Fatal Rulebased Simulation Errors
These errors occur when a rule is fired too many times within any timestep. Rules may not be evaluated more than the Maximum Rule Executions Per Timestep specified in the Rulebased Simulation Run Parameters dialog. The default maximum executions is 50. From the View menu of the Run Control dialog, select Rulebased Simulation Run Parameters... to open the dialog to change this value. A rule firing more than 50 times is usually an indicator of a circularity in the rule logic. Excessive rule firing and redispatching is an indication of a circularity in the ruleset design; one or more rules are dependent on the slots which they are setting. Even in the most complex rulesets, individual rules should not fire more than a few times in any given timestep. Unchecked, circularities would continue indefinitely, or until the user terminates the executable. But, when a rule is fired more than the maximum executions, the Rulebased Simulation Controller stops the run and posts this error to the Diagnostics Output Window, “Max rule executions exceeded for timestep.” Luckily, these types of circularities are rare.
Example 4.10  Example:
Circularities in rulesets are easy to create consciously but they rarely happen by accident.
An example of a circular ruleset which causes no dispatching, is shown below:
1. Data.A[] = IF ( Data.B[] == 1 ) THEN
0
ELSE
1
2. Data.B[] = IF ( Data.A[] == 1 ) THEN
1
ELSE
0
3. Data.A[] = 1
The Rulebased Simulation would proceed as follows:
1. Rule #3 fires and sets Data.A to 1.
2. Rule #2 fires and sets Data.B to 1.
3. Rule #1 fires and sets Data.A to 0. Rule #2 goes back on the Agenda.
4. Rule #2 fires and sets Data.B to 0. Rule #1 goes back on the Agenda.
5. Rule #1 fires and sets Data.A to 1. Rule #2 goes back on the Agenda.
6. The steps above are repeated another 24 times before the Rulebased Simulation Controller stops the run.
Understanding RPL Evaluation
RiverWare provides the following tools for helping the user to understand RPL evaluation and its consequences in rules, goals, methods, and expression slots:
• Debugging: The user is able to pause execution, look at the values of RPL expressions as they happen, and then step through RPL expressions. See RPL Debugger for details.
• Diagnostics: Print out messages when rules or functions are executed and evaluated. Several categories are especially relevant to the execution of RPL policy, including Rule Execution, Function Execution, and well placed Print Statements. See Rulebased Simulation Diagnostics for details.
• Rulebased Simulation Model Run Analysis tool: Provides information on the rules and policy that caused an object to dispatch. See Rulebased Simulation for details.
• RPL Set Analysis Tool: Provides information about the number of executions and execution times for RPL blocks and statements. See RPL Analysis Tool for details.
With these tools it is possible to examine RPL behavior and make changes if that behavior is deemed to be unintended. For complex policies this process of policy debugging can be very time consuming. This document describes Debugging and the RPL Set Analysis Tool and provides links to documentation on diagnostics and the model run analysis tool.
Revised: 08/02/2021