Skip to content

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

@rburghol

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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions