Abstract Model Representation

The Abstract Model representation allows a separation of concern between translation and building. Translation involves anything that happens from the moment the source code of the original model is loaded into memory up to the creation of the Abstract Model representation. Similarly, the building will be everything that takes place between the Abstract Model and the source code of the model written in a programming language different than that of the original model.This approach allows to easily include new code to the translation or or building process, without the the risk of affecting one another.

The AbstractModel object should retain as much information from the original model as possible. Although the information is not used in the output code, it may be necessary for other future output languages or for improvements in the currently supported outputs. For example, currently unchangeable constants (== defined in Vensim) are treated as regular components with Python, but in the future we may want to protect them from user interaction.

The lowest level of this representation is the AbstractSyntax Tree (AST). This includes all the operations and calls in a given component expression.

Main abstract structures

The main Abstract dataclasses provide the structure for the information from the Component level to the Model level. This classes are hierarchical An AbstractComponent will be inside an AbstractElement, which is inside an AbstractSection, which is a part of an AbstractModel.

class pysd.translators.structures.abstract_model.AbstractComponent(subscripts: Tuple[List[str], List[List[str]]], ast: object, type: str = 'Auxiliary', subtype: str = 'Normal')[source]

Dataclass for a regular component.

Parameters:
  • subscripts (tuple) – Tuple of length two with first argument the list of subscripts in the variable definition and the second argument the list of subscripts list that must be ignored (EXCEPT).

  • ast (object) – The AbstractSyntaxTree of the component expression

  • type (str (optional)) – The type of component. ‘Auxiliary’ by default.

  • subtype (str (optional)) – The subtype of component. ‘Normal’ by default.

dump(depth=None, indent='') str[source]

Dump the component to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

class pysd.translators.structures.abstract_model.AbstractUnchangeableConstant(subscripts: Tuple[List[str], List[List[str]]], ast: object, type: str = 'Constant', subtype: str = 'Unchangeable')[source]

Dataclass for an unchangeable constant component. This class is a child of AbstractComponent.

Parameters:
  • subscripts (tuple) – Tuple of length two with first argument the list of subscripts in the variable definition and the second argument the list of subscripts list that must be ignored (EXCEPT).

  • ast (object) – The AbstractSyntaxTree of the component expression

  • type (str (optional)) – The type of component. ‘Constant’ by default.

  • subtype (str (optional)) – The subtype of component. ‘Unchangeable’ by default.

class pysd.translators.structures.abstract_model.AbstractLookup(subscripts: Tuple[List[str], List[List[str]]], ast: object, type: str = 'Lookup', subtype: str = 'Hardcoded', arguments: str = 'x')[source]

Dataclass for a lookup component. This class is a child of AbstractComponent.

Parameters:
  • subscripts (tuple) – Tuple of length two with first argument the list of subscripts in the variable definition and the second argument the list of subscripts list that must be ignored (EXCEPT).

  • ast (object) – The AbstractSyntaxTree of the component expression

  • arguments (str (optional)) – The name of the argument to use. ‘x’ by default.

  • type (str (optional)) – The type of component. ‘Lookup’ by default.

  • subtype (str (optional)) – The subtype of component. ‘Hardcoded’ by default.

class pysd.translators.structures.abstract_model.AbstractData(subscripts: Tuple[List[str], List[List[str]]], ast: object, type: str = 'Data', subtype: str = 'Normal', keyword: str | None = None)[source]

Dataclass for a data component. This class is a child of AbstractComponent.

Parameters:
  • subscripts (tuple) – Tuple of length two with first argument the list of subscripts in the variable definition and the second argument the list of subscripts list that must be ignored (EXCEPT).

  • ast (object) – The AbstractSyntaxTree of the component expression

  • keyword (str or None (optional)) – The data object keyword (‘interpolate’, ‘hold_backward’, ‘look_forward’, ‘raw’). Default is None.

  • type (str (optional)) – The type of component. ‘Data’ by default.

  • subtype (str (optional)) – The subtype of component. ‘Normal’ by default.

dump(depth=None, indent='') str[source]

Dump the component to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

class pysd.translators.structures.abstract_model.AbstractElement(name: str, components: List[AbstractComponent], units: str = '', limits: tuple = (None, None), documentation: str = '')[source]

Dataclass for an element.

Parameters:
  • name (str) – The name of the element.

  • components (list) – The list of AbstractComponents that define this element.

  • units (str (optional)) – The units of the element. ‘’ by default.

  • limits (tuple (optional)) – The limits of the element. (None, None) by default.

  • units – The documentation of the element. ‘’ by default.

dump(depth=None, indent='') str[source]

Dump the element to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

class pysd.translators.structures.abstract_model.AbstractControlElement(name: str, components: List[AbstractComponent], units: str = '', limits: tuple = (None, None), documentation: str = '')[source]

Dataclass for a control element. This class is a child of AbstractElement and has the same attributes.

Parameters:
  • name (str) – The name of the element.

  • components (list) – The list of AbstractComponents that define this element.

  • units (str (optional)) – The units of the element. ‘’ by default.

  • limits (tuple (optional)) – The limits of the element. (None, None) by default.

  • units – The documentation of the element. ‘’ by default.

class pysd.translators.structures.abstract_model.AbstractSubscriptRange(name: str, subscripts: list | str | dict, mapping: list)[source]

Dataclass for a subscript range.

Parameters:
  • name (str) – The name of the element.

  • subscripts (list or str or dict) – The subscripts as a list of strings for a regular definition, str for a copy definition and as a dict for a GET XLS/DIRECT definition.

  • mapping (list) – The list of subscript range that can be mapped to.

dump(depth=None, indent='') str[source]

Dump the subscript range to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

class pysd.translators.structures.abstract_model.AbstractConstraint(name: str, subscripts: list | str | dict, expression: str)[source]

Dataclass for a constraint

Parameters:
  • name (str) – Name of the constraint variable.

  • subscripts (list or str or dict) – The subscripts as a list of strings for a regular definition, str for a copy definition and as a dict for a GET XLS/DIRECT definition.

  • expression (str) – Unparsed constraint expression.

class pysd.translators.structures.abstract_model.AbstractTestInput(name: str, subscripts: list | str | dict, expression: str)[source]

Dataclass for a test inputs

Parameters:
  • name (str) – Name of the test inputs variable.

  • subscripts (list or str or dict) – The subscripts as a list of strings for a regular definition, str for a copy definition and as a dict for a GET XLS/DIRECT definition.

  • expression (str) – Unparsed test inputs expression.

class pysd.translators.structures.abstract_model.AbstractSection(name: str, path: Path, type: str, params: List[str], returns: List[str], subscripts: Tuple[AbstractSubscriptRange], elements: Tuple[AbstractElement], constraints: Tuple[AbstractConstraint], test_inputs: Tuple[AbstractTestInput], split: bool, views_dict: dict | None)[source]

Dataclass for a section.

Parameters:
  • name (str) – Section name. ‘__main__’ for the main section or the macro name.

  • path (pathlib.Path) – Section path. It should be the model name for main section and the clean macro name for a macro.

  • section_type (str ('main' or 'macro')) – The section type.

  • params (list) – List of params that takes the section. In the case of main section it will be an empty list.

  • returns (list) – List of variables that returns the section. In the case of main section it will be an empty list.

  • subscripts (tuple) – Tuple of AbstractSubscriptRanges that are defined in the section.

  • elements (tuple) – Tuple of AbstractElements that are defined in the section.

  • constraints (tuple) – Tuple of AbstractConstraints that are defined in the section.

  • test_inputs (tuple) – Tuple of TestInputs that are defined in the section.

  • split (bool) – If split is True the created section will split the variables depending on the views_dict.

  • views_dict (dict) – The dictionary of the views. Giving the variables classified at any level in order to split them by files.

dump(depth=None, indent='') str[source]

Dump the section to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

class pysd.translators.structures.abstract_model.AbstractModel(original_path: Path, sections: Tuple[AbstractSection])[source]

Dataclass for a model.

Parameters:
  • original_path (pathlib.Path) – The path to the original file.

  • sections (tuple) – Tuple of AbstractSectionss that are defined in the model.

dump(depth=None, indent='') str[source]

Dump the model to a printable version.

Parameters:
  • depth (int (optional)) – The number of depht levels to show in the dumped output. Default is None which will dump everything.

  • indent (str (optional)) – The indent to use for a lower level object. Default is ‘’.

Abstract structures for the AST

The following abstract structures are used to build the Abstract Syntax Tree (AST). In general, there is no hierarchy between them. For example, an ArithmeticStructure can contain a CallStructure which at the same time contains another ArithmeticStructure. However, some of them could not be inside another structures due to the restrictions of the source languages. For example, the GetConstantsStructure cannot be a part of another structure because it has to appear after the ‘=’ sign in Vensim and not be followed by anything else.

class pysd.translators.structures.abstract_expressions.AbstractSyntax[source]

Generic class. All Abstract Synax structured are childs of that class. Used for typing.

class pysd.translators.structures.abstract_expressions.ArithmeticStructure(operators: list, arguments: list)[source]

Dataclass for an arithmetic structure.

Parameters:
  • operators (list) – List of operators applied between the arguments

  • arguments (list) – The arguments of the arithmetics operations.

class pysd.translators.structures.abstract_expressions.LogicStructure(operators: list, arguments: list)[source]

Dataclass for a logic structure.

Parameters:
  • operators (list) – List of operators applied between the arguments

  • arguments (list) – The arguments of the logic operations.

class pysd.translators.structures.abstract_expressions.SubscriptsReferenceStructure(subscripts: tuple)[source]

Dataclass for a subscript reference structure.

Parameters:

subscripts (tuple) – The list of subscripts referenced.

class pysd.translators.structures.abstract_expressions.ReferenceStructure(reference: str, subscripts: SubscriptsReferenceStructure | None = None)[source]

Dataclass for an element reference structure.

Parameters:
class pysd.translators.structures.abstract_expressions.CallStructure(function: ReferenceStructure, arguments: tuple)[source]

Dataclass for a call structure.

Parameters:
  • function (ReferenceStructure) – The reference of the callable.

  • arguments (tuple) – The list of arguments used for calling the function.

class pysd.translators.structures.abstract_expressions.GameStructure(expression: AbstractSyntax | float)[source]

Dataclass for a game structure.

Parameters:

expression (AST) – The expression inside the game call.

class pysd.translators.structures.abstract_expressions.AllocateAvailableStructure(request: AbstractSyntax, pp: AbstractSyntax, avail: AbstractSyntax | float)[source]

Dataclass for a Allocate Available structure.

Parameters:
class pysd.translators.structures.abstract_expressions.AllocateByPriorityStructure(request: AbstractSyntax, priority: AbstractSyntax, size: AbstractSyntax | int, width: AbstractSyntax | float, supply: AbstractSyntax | float)[source]

Dataclass for a Allocate By Priority structure.

Parameters:
class pysd.translators.structures.abstract_expressions.InitialStructure(initial: AbstractSyntax | float)[source]

Dataclass for a initial structure.

Parameters:

initial (AST) – The expression inside the initial call.

class pysd.translators.structures.abstract_expressions.IntegStructure(flow: AbstractSyntax | float, initial: AbstractSyntax | float, non_negative: bool | None = False)[source]

Dataclass for an integ/stock structure.

Parameters:
  • flow (AST) – The flow of the stock.

  • initial (AST) – The initial value of the stock.

  • non_negative (bool (optional)) – If True the stock cannot be negative. Default is False.

class pysd.translators.structures.abstract_expressions.DelayStructure(input: AbstractSyntax | float, delay_time: AbstractSyntax | float, initial: AbstractSyntax | float, order: float)[source]

Dataclass for a delay structure.

Parameters:
  • input (AST) – The input of the delay.

  • delay_time (AST) – The delay time value of the delay.

  • initial (AST) – The initial value of the delay.

  • order (float) – The order of the delay.

class pysd.translators.structures.abstract_expressions.DelayNStructure(input: AbstractSyntax | float, delay_time: AbstractSyntax | float, initial: AbstractSyntax | float, order: AbstractSyntax | float)[source]

Dataclass for a delay n structure.

Parameters:
  • input (AST) – The input of the delay.

  • delay_time (AST) – The delay time value of the delay.

  • initial (AST) – The initial value of the delay.

  • order (float) – The order of the delay.

class pysd.translators.structures.abstract_expressions.DelayFixedStructure(input: AbstractSyntax | float, delay_time: AbstractSyntax | float, initial: AbstractSyntax | float)[source]

Dataclass for a delay fixed structure.

Parameters:
  • input (AST) – The input of the delay.

  • delay_time (AST) – The delay time value of the delay.

  • initial (AST) – The initial value of the delay.

class pysd.translators.structures.abstract_expressions.SmoothStructure(input: AbstractSyntax | float, smooth_time: AbstractSyntax | float, initial: AbstractSyntax | float, order: float)[source]

Dataclass for a smooth structure.

Parameters:
  • input (AST) – The input of the smooth.

  • delay_time (AST) – The smooth time value of the smooth.

  • initial (AST) – The initial value of the smooth.

  • order (float) – The order of the smooth.

class pysd.translators.structures.abstract_expressions.SmoothNStructure(input: AbstractSyntax | float, smooth_time: AbstractSyntax | float, initial: AbstractSyntax | float, order: AbstractSyntax | float)[source]

Dataclass for a smooth n structure.

Parameters:
  • input (AST) – The input of the smooth.

  • delay_time (AST) – The smooth time value of the smooth.

  • initial (AST) – The initial value of the smooth.

  • order (float) – The order of the smooth.

class pysd.translators.structures.abstract_expressions.TrendStructure(input: AbstractSyntax | float, average_time: AbstractSyntax | float, initial_trend: AbstractSyntax | float)[source]

Dataclass for a trend structure.

Parameters:
  • input (AST) – The input of the trend.

  • average_time (AST) – The average time value of the trend.

  • initial_trend (AST) – The initial trend value of the trend.

class pysd.translators.structures.abstract_expressions.ForecastStructure(input: AbstractSyntax | float, average_time: AbstractSyntax | float, horizon: AbstractSyntax | float, initial_trend: AbstractSyntax | float)[source]

Dataclass for a forecast structure.

Parameters:
  • input (AST) – The input of the forecast.

  • averae_time (AST) – The average time value of the forecast.

  • horizon (float) – The horizon value of the forecast.

  • initial_trend (AST) – The initial trend value of the forecast.

class pysd.translators.structures.abstract_expressions.SampleIfTrueStructure(condition: AbstractSyntax | float, input: AbstractSyntax | float, initial: AbstractSyntax | float)[source]

Dataclass for a sample if true structure.

Parameters:
  • condition (AST) – The condition of the sample if true

  • input (AST) – The input of the sample if true.

  • initial (AST) – The initial value of the sample if true.

class pysd.translators.structures.abstract_expressions.LookupsStructure(x: tuple, y: tuple, x_limits: tuple, y_limits: tuple, type: str)[source]

Dataclass for a lookup structure.

Parameters:
  • x (tuple) – The list of the x values of the lookup.

  • y (tuple) – The list of the y values of the lookup.

  • x_limits (tuple) – The minimum and maximum value of x.

  • y_limits (tuple) – The minimum and maximum value of y.

  • type (str) – The interpolation method.

class pysd.translators.structures.abstract_expressions.InlineLookupsStructure(argument: AbstractSyntax | float, lookups: LookupsStructure)[source]

Dataclass for an inline lookup structure.

Parameters:
  • argument (AST) – The argument of the inline lookup.

  • lookups (LookupStructure) – The lookups definition.

class pysd.translators.structures.abstract_expressions.DataStructure[source]

Dataclass for an empty data structure.

Parameters:

None

class pysd.translators.structures.abstract_expressions.GetLookupsStructure(file: str, tab: str, x_row_or_col: str, cell: str)[source]

Dataclass for a get lookups structure.

Parameters:
  • file (str) – The file path where the data is.

  • tab (str) – Tab name from which the data is read. If file type is not a spreadsheet this will be used as a separator.

  • x_row_or_col (str) – The pointer to the cell or cellrange name that defines the interpolation series data.

  • cell (str) – The pointer to the cell or the cellrange name that defines the data.

class pysd.translators.structures.abstract_expressions.GetDataStructure(file: str, tab: str, time_row_or_col: str, cell: str)[source]

Dataclass for a get lookups structure.

Parameters:
  • file (str) – The file path where the data is.

  • tab (str) – Tab name from which the data is read. If file type is not a spreadsheet this will be used as a separator.

  • time_row_or_col (str) – The pointer to the cell or cellrange name that defines the interpolation time series data.

  • cell (str) – The pointer to the cell or the cellrange name that defines the data.

class pysd.translators.structures.abstract_expressions.GetConstantsStructure(file: str, tab: str, cell: str)[source]

Dataclass for a get lookups structure.

Parameters:
  • file (str) – The file path where the data is.

  • tab (str) – Tab name from which the data is read. If file type is not a spreadsheet this will be used as a separator.

  • cell (str) – The pointer to the cell or the cellrange name that defines the data.