IR
Goal: separate the problem parsing from the problem construction.
problem parsing is delegated to a new Module named SimpleModelIR:
module SimpleModelIR
using MacroTools: postwalk
include("utils.jl")
include("types.jl")
include("build_ir.jl")
include("normalize_ir.jl")
export
AbstractODEStatement,
AssignStatement,
IfStatement,
ForStatement,
WhileStatement,
ExprStatement,
ODEFunctionIR,
build_ir,
normalize_ir,
problem_to_normalized_ir,
end
The buildir_ function loops through the user code expression and builds an ODEFunctionIR(statement). i.e the expression will be changed to a vector of statements. Each statement is an object of type ....<: AbstractODEStatement The normalizeir_ function loops over the vectors and call personalized functions such as changeVarNamesparams_ or normalizeifstatement! to change composite if-statements to simple if-statements.
Example:
function simpleModel(dy,y,p,t)# api requires four args
U = 24.0;
rd,rs=p;
il=y[1]
id=(il*rs-U)/(rd+rs)
dy[1] =id
dy[2]=il
if t>0 || y[2]>0 && y[1]>y[2]
y[1]=0.0
else
y[2]=0.0
end
end
buildir –>
ir = SimpleModelIR.ODEFunctionIR(SimpleModelIR.AbstractODEStatement[SimpleModelIR.AssignStatement(:U, 24.0),
SimpleModelIR.AssignStatement(:((rd, rs)), :p), SimpleModelIR.AssignStatement(:il, :(y[1])), SimpleModelIR.AssignStatement(:id, :
((il * rs - U) / (rd + rs))), SimpleModelIR.AssignStatement(:(dy[1]), :id), SimpleModelIR.AssignStatement(:(dy[2]), :il),
SimpleModelIR.IfStatement(:(t > 0 || y[2] > 0 && y[1] > y[2]), :(if t > 0 || y[2] > 0 && y[1] > y[2]
y[1] = 0.0
else
y[2] = 0.0
end))])
normalizeir –>
ir = SimpleModelIR.ODEFunctionIR(SimpleModelIR.AbstractODEStatement[SimpleModelIR.AssignStatement(:U, 24.0),
SimpleModelIR.AssignStatement(:((rd, rs)), :p), SimpleModelIR.AssignStatement(:il, :(q[1])), SimpleModelIR.AssignStatement(:id, :
((q[1] * p[2] - 24.0) / (p[1] + p[2]))), SimpleModelIR.AssignStatement(:(dy[1]), :((q[1] * p[2] - 24.0) / (p[1] + p[2]))),
SimpleModelIR.AssignStatement(:(dy[2]), :(q[1])), SimpleModelIR.IfStatement(:(t - 0.0), :(if t - 0.0
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
else
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
end)), SimpleModelIR.IfStatement(:(q[2] - 0.0), :(if q[2] - 0.0
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
else
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
end)), SimpleModelIR.IfStatement(:(q[1] - q[2]), :(if q[1] - q[2]
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
else
if t > 0.0 || q[2] > 0.0 && q[1] > q[2]
q[1] = 0.0
else
q[2] = 0.0
end
end))])
QuantizedSystemSolver.SimpleModelIR.problem_to_normalized_ir
— Methodproblem_to_normalized_ir(expr::Expr, stateVarName::Symbol, discrParamName::Symbol)
Converts a symbolic problem expression into a normalized intermediate representation (IR).
Arguments
expr::Expr
: The symbolic expression representing the problem to be normalized.stateVarName::Symbol
: The symbol representing the state variable in the problem.discrParamName::Symbol
: The symbol representing the discrete variable in the problem.
Returns
probInfo
: A structure containing the normalized IR and associated problem information.
Description
This function processes the input symbolic expression, extracting relevant information and transforming it into a normalized IR suitable for further analysis or code generation. It uses the provided state variable and discretization parameter names to correctly interpret the structure of the problem. this process is delegated to buildir and normalizeir functions.
QuantizedSystemSolver.SimpleModelIR.build_ir
— Methodbuild_ir(expr::Expr)
Converts a symbolic expression into an ODEFunctionIR representation.
Arguments
expr::Expr
: The symbolic expression to be converted into an ODEFunctionIR.
Returns
ODEFunctionIR
: An intermediate representation of the ODE function, encapsulating the parsed
QuantizedSystemSolver.SimpleModelIR.AbstractODEStatement
— TypeAbstractODEStatement
An abstract type representing a single statement in the user code. This serves as a base type for various specific types of statements that can be part of an ODE function's intermediate representation (IR). It is used to encapsulate different kinds of operations, such as assignments, conditional statements, loops, and expressions, allowing for a structured representation of the ODE function's logic.
QuantizedSystemSolver.SimpleModelIR.AssignStatement
— TypeAssignStatement
Represents an assignment statement within an ODE statement in the intermediate representation (IR) of a simple model. This mutable struct is used to store information about lhs and rhs parts of an assignment.
QuantizedSystemSolver.SimpleModelIR.IfStatement
— TypeIfStatement
Represents a conditional (if) statement within the intermediate representation (IR) of a simple model ODE system.
Fields
condition
: The condition expression to evaluate. it represents the zero-crossing function for an event.body
: The statements to execute if the condition is true. it contains an expression of the whole if-statment. It will be used as the actual execution of the event.
Usage
Used to model control flow in the IR for ODE problem generation.
QuantizedSystemSolver.SimpleModelIR.ForStatement
— TypeForStatement
Represents a for
loop statement within the intermediate representation (IR) of an ODE problem.
Description
This mutable struct is a subtype of AbstractODEStatement
and is used to represent a for
loop that is used to define differential equations.
Example
QuantizedSystemSolver.SimpleModelIR.ExprStatement
— TypeExprStatement
A mutable struct representing an expression statement within the ODE problem intermediate representation (IR).
Description
ExprStatement
is used to encapsulate a single expression that was not handled by other specific statement types like AssignStatement
, IfStatement
, ForStatement
, or WhileStatement
. It allows for the inclusion of arbitrary expressions in the IR, which can be useful for representing complex operations or computations that do not fit neatly into the other categories.