Skip to content

specl: CONDITIONAL/IF-THEN (parser and code) #198

Description

@rburghol

@timcera

Overview

  • This enables nested IF-THEN-ELSE statements in hsp2.
  • Execution should follow an "as appears" in UCI or in hdf5 table (or CSV if applicable)
  • Tasks:
    • Parse complicated IF-THEN statement and store in h5/pandas friendly array
    • Add pointer to related IF-THEN in special ACTIONS parser (see specl: ACTIONS (parser and code) #105)
    • Enable UVNAME to facilitate evaluation of IF... (see specl: UVNAME (parser and code) #106 )
    • Develop data model for tokenized runtime object SpecialCondition in om_special_condition.py
    • Add runtime token for parent_ix and sibling_ix in SpecialAction and step_special_action() (see specl: ACTIONS (parser and code) #105)
    • Develop runtime execution step_special_condition() in om_special_condition.py

Examples

Data Model

Path and Column Definitions for hdf5

  • Path: /SPECACTIONS/conditions
  • cond_id: unique integer ID for this condition from parsing
  • parent_id: unique integer ID for containing condition if applicable
  • sibling_id: unique integer ID for most immediate prior conditions that share the same parent_id i.e. related ELSE statements (will be empty if not nested if/else) -- will only be the related statement that appears before the statement in the UCI
  • expression: string representation of conditional (normally as outlined in the UCI, but could be defined in hdf5 or CSV)

Example Table Entry

  • Shows a condition that has no parent, no siblings, just a stand-alone IF-THEN block of actions
cond_id parent_ix sibling_ix expression
0 -1 -1 'IF (precx1 > 6.000) THEN'

Code

UCI excerpt (see

Example 1: Adjust infiltration exp under high precip daily total.

***User-Defined Variable Quantity Line
  UVQUAN precx1 PERLND   1 PREC             3                 DY 14 SUM

*** ACTIONS
***optyp range dc ds yr  mo da hr mn d t   vari  s1 s2 s3 ac  value    tc ts num
  <****><-><--><><-><--><-><-><-><-><><>  <----><-><-><-><-><--------> <> <-><->

***Action Lines for INFEXP
IF (precx1 >  6.000) THEN
  PERLND  1                            3  INFEXP          =  8.0000000
ELSE
  PERLND  1                            3  INFEXP          =  2.0000000
END IF

Example 2:

***Action Lines for INFEXP
IF (precx1 >  6.000) THEN
  PERLND  1                            3  INFEXP          =  8.0000000
ELSE
  PERLND  1                            3  INFEXP          =  2.0000000
END IF

Operational model Design:

  • Each IF statement will be given it's own state_ix, and it's value will be 1/0 depending on the conditional evaluation at each time step (the step_model() method).
    • ix: Their state_ix value is their definitive active/inactive status
    • parent_ix: They will have an attribute that points to the state_ix of a parent conditional statement if it is nested inside another IF-THEN (this value will be -1 if they are not contained)
    • arg1_ix, arg2_ix, op: They will have attributes that define their input state_ix pointers, and their operator (an integer)
    • $V = AND(C_{self}, C_{p})$; where $C_{self}$ = conditional statement result and $C_{p}$ = parent conditional (if present)
  • Sub-conditionals ELSE/ELSE IF:
    • ix: Their state_ix value is their definitive active/inactive status
    • parent_ix: They will have an attribute that points to the state_ix of a parent conditional statement if it is nested inside another IF-THEN (this value will be -1 if they are not contained)
    • sibling_ix: The state_ix index of their prior sibling conditional. (assumes the activity state of the sibling aggregates any/all prior siblings state)
    • Their state_ix ACTIVE status will be the NOR of all previous sibling elements of their conditional tree and their own conditional evaluation.
    • $V = AND(C_{self}, C_{p}, NOR(C_{sibs})$; where $C_{self}$ = conditional statement result and $C_{p}$ = parent conditional (if present) and $C_{sibs}$ = siblings 1 to n value
    • Example:
      • IF an ELSE IF statement is preceded by another ELSE IF and an IF statement,
      • $V = AND(C_{self}, C_{p}, NOT(C_{sib} )$
      • $1 = AND(1, 1, NOT(0) )$
      • $0 = AND(1, 0, NOT(0) )$
      • $0 = AND(1, 1, NOT(1) )$
  • All conditional components will be evaluated during the beginning of the step() evaluation (so that changes of state are evaluated in the moment)
  • @njit code will check enabled state value and return if enabled == 0 (this should be quite fast, despite evaluating many times)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions