文西姆转换

PySD允许解析Vensim .mdl 文件并将结果转换为 AbstractModel 对象,稍后(构建过程)可以用于以另一种编程语言构建模型。

转换工作流

以下转换工作流程允许在解析其内容的同时拆分Vensim文件,以构建 AbstractModel object.工作流程可总结如下:

  1. Vensim file :将模型方程从草图中拆分,并允许将模型拆分为部分(主要部分和宏部分)。

  2. Vensim section :是一套完整的变量和定义,可集成。然后,Vensim部分可以拆分为模型表达。

  3. Vensim element :mdl文件中的定义,可以是后缀(子)范围定义或变量定义。它包括单位和评论。同一变量的定义分组在同一个 AbstractElement object.允许解析其左侧(LHS)以获取脚注(子)范围或变量的名称,并根据使用的分配操作符(=,==,:=,(),:)将其作为特定类型的组件返回

  4. Vensim component :变量定义的分类对象,它取决于用于定义变量的操作符。可以解析其右侧(RHS)以获取该表达的抽象语法树(AST)。

一旦按照前面的步骤解析并分解了模型, AbstractModel 已经回来了

Vensim文件部分

文西姆文件

VensimFile类允许读取原始的Vensim模型文件,使用File SectionsVisitor将其解析为Section元素,使用SketchVisitor解析其草图,以便对每个视图的变量进行分类。最终结果可以被输出到AbstractModel类,以便用另一种编程语言构建模型。

class pysd.translators.vensim.vensim_file.VensimFile(mdl_path: str | Path, encoding: None | str = None)[源代码]

VensimFile类允许解析mdl文件。创建对象时,模型文件将自动打开;不必要的制表符、空白和断点将被删除;草图将从模型方程中拆分。

参数:
  • mdl_path (str or pathlib.Path) -- Vensim模型的路径。

  • encoding (str or None (optional)) -- 源模型文件的编码。如果无,则将从模型中读取编码,如果模型文件中未定义编码,则将设置为“UTF-8”。默认为无。

property verbose

将模型信息打印到标准输出。

parse(parse_all: bool = True) None[源代码]

使用“parsing_grammars/file_sections. pe”中给出的语法和FilesSectionsVisitor类来精简地解析模型文件,以访问解析的表达。

这会破坏VenssimSections中的模型文件,该文件对应于主模型部分和宏。

参数:

parse_all (bool (optional)) -- 如果为True,将自动解析创建的VensimSection对象。否则,这些对象将仅添加到self.sections中,而不会解析。默认为True。

parse_sketch(subview_sep: List[str]) None[源代码]

使用“sparning_grammars/sketch. pe”中给出的语法和SketchVisitor类来精简地解析模型的草图,以访问解析的表达。

它将修改第一部分的views_dict,包括按视图对变量进行分类的字典。这个,应该在调用self.parse方法后调用。

参数:

subview_sep (list) -- 用于对文件夹和子目录中的模型视图进行分类的分隔符列表。分离器的顺序必须与视图名称中出现的顺序相同。例如,如果视图被命名为“economy:demand.exports”,如果subview_sep= [":", "."] 此视图的变量将包含在文件“exports.py”和economy/demand文件夹中。

get_abstract_model() AbstractModel[源代码]

实例化构建期间使用的AbstractModel对象。该方法应该在解析模型(self.parse)之后调用,如果您想要按视图拆分变量,也应该在解析草图(self.parse_sketch)之后调用。这会自动从模型部分调用get_abstract_section方法。

返回:

AbstractModel --抽象模型对象,可用于以另一种语言构建模型。

返回类型:

AbstractModel

文西姆部分

Section类允许使用SectionElementsVisitor将模型部分解析为元素。最终结果可以导出到AbstractSection类,以便用另一种编程语言构建模型。节可以是主模型(没有宏),也可以是宏定义。

class pysd.translators.vensim.vensim_section.Section(name: str, path: Path, section_type: str, params: List[str], returns: List[str], content: str, split: bool, views_dict: dict | None)[源代码]

Section类允许解析模型部分的元素。

参数:
  • name (str) -- 部分名称。即,“__main__”代表主要部分,宏名称代表宏。

  • path (pathlib.Path) -- 部分路径。主要部分的模型名称和宏的干净宏名称。

  • section_type (str ('main' or 'macro')) -- 节类型。

  • params (list) -- 该部分采用的参数列表。如果是主要部分,那么它将是一个空列表。

  • returns (list) -- 返回该部分的变量列表。如果是主要部分,那么它将是一个空列表。

  • content (str) -- 部分内容为字符串。

  • split (bool) -- 如果为True,则创建的部分将根据views_dict拆分变量。

  • views_dict (dict) -- 观点词典。给出任何级别分类的变量,以便按文件将它们拆分。

property verbose

将部分信息打印到标准输出。

parse(parse_all: bool = True) None[源代码]

使用parsing_grammars/section_elements.peg中给出的语法和SectionElementsVisitor类来访问解析的表达式,使用parsimonious来解析section对象。

这将打破部分 (__main__ 或宏)在VenssimElements中,它们是每个模型表达LHS和RHS,具有已经解析的单元和描述。

参数:

parse_all (bool (optional)) -- 如果为True,将自动解析创建的VensimElement对象。否则,这些对象将仅添加到self.elements中,而不会解析。默认为True。

get_abstract_section() AbstractSection[源代码]

实例化将在构建过程中使用的AbstractSection类的对象。应在解析部分(self.parse)后调用此方法。该方法由Model的get_abstract_mode方法自动调用,并自动生成AbstractSubScript范围并将组件合并到元素中。它还从每个模型组件调用get_abstract_components方法。

返回:

AbstractSection -- AbstractSection对象,可用于用另一种编程语言构建模型。

返回类型:

AbstractSection

文西姆元素

Element类允许解析模型方程的LHS。根据LHS值,将返回一个SubscriptRange对象或一个Component对象。有四种组件类型:

  • 组件:常规组件,用“=”定义。

  • UnchangeableConstant:不可更改的常数,用“==”定义。

  • 数据:数据组件,用“:=”定义

语法组件有自己的解析器来处理表达的RHS,而其他3个组件共享同一个解析器。解析组件的最终结果可以被输出到AbstractElement对象,以便用其他编程语言构建模型。可以定义另外两个类似元素的对象,它们仅用于测试:

  • 约束:现实检查的约束,用“:THE CONDITION:”定义

  • 测试输入:用于测试的输入,用“:测试输入:”定义

class pysd.translators.vensim.vensim_element.Element(equation: str, units: str, documentation: str)[源代码]

元素对象允许解析Vensim表达式的LHS。

参数:
  • equation (str) -- Vensim文件中的原始方程。

  • units (str) -- 具有极限的元素单位,即第一个“~”符号后面的内容。

  • documentation (str) -- 元素的注释,即第二个“~”符号后面的内容。

property verbose

将元素信息打印到标准输出。

parse() object[源代码]

使用parsing_grammars/element_object.peg中给出的语法和类ElementsParsentVisitor来访问解析的表达式,使用parsimonious解析Element对象。

将方程的LHS与RHS分开。如果返回的对象是SubwrittRange,则无需进行更多解析。否则,应解析返回对象(组件)的RHS以获取AbstractHandler树。

返回:

self.component --脚注范围定义对象或组件对象。

返回类型:

SubscriptRange or Component

class pysd.translators.vensim.vensim_element.SubscriptRange(name: str, definition: List[str] | str | dict, mapping: List[str] = [])[源代码]

后缀范围定义,由Vensim中的“:”或“<->”定义。

property verbose

将订阅范围信息打印到标准输出。

get_abstract_subscript_range() AbstractSubscriptRange[源代码]

实例化用于构建的AbstractSubwrittRange对象。此方法由Sections的get_abstract_section方法自动调用。

返回:

AbstractSubscriptRange --AbstractSubwrittRange对象,可用于用另一种编程语言构建模型。

返回类型:

AbstractSubscriptRange

class pysd.translators.vensim.vensim_element.Component(name: str, subscripts: Tuple[list, list], expression: str)[源代码]

由Vensim中的“名称= expr”定义的模型组件。

参数:
  • name (str) -- 组件的原始名称。

  • subscripts (tuple) -- 长度为2的二元组,变量定义中的后缀列表作为第一个参数,出现在:EXCEPT:关键字(如果使用)后面的后缀列表作为第二个参数。

  • expression (str) -- 要分析的元素、表达的RHS。

parse() None[源代码]

使用“sparning_grammars/components.peg”中给出的语法和EquationVisitor类来精简解析组件对象,以访问表达的RHS。

get_abstract_component() AbstractComponent | AbstractLookup[源代码]

获取用于构建的抽象组件。此方法由Sections的get_abstract_section方法自动调用。

返回:

AbstractComponent --抽象组件对象,可用于以另一种语言构建模型。如果分量方程包括外部查找(GET XLS/DIRECT LOOKUPS),则将使用AbstractSYS类。

返回类型:

AbstractComponent or AbstractLookup

class pysd.translators.vensim.vensim_element.UnchangeableConstant(name: str, subscripts: Tuple[list, list], expression: str)[源代码]

由Vensim中的“Name == expr”定义的不可更改的常数。此类继承自Components类。

参数:
  • name (str) -- 组件的原始名称。

  • subscripts (tuple) -- 长度为2的二元组,变量定义中的脚注列表作为第一个参数,出现在:EXCEPT:关键字(如果使用)后面的脚注列表作为第二个参数。

  • expression (str) -- 要分析的元素、表达的RHS。

get_abstract_component() AbstractUnchangeableConstant[源代码]

获取用于构建的抽象组件。此方法由Sections的get_abstract_section方法自动调用。

返回:

AbstractComponent --抽象组件对象,可用于以另一种语言构建模型。

返回类型:

AbstractUnchangeableConstant

class pysd.translators.vensim.vensim_element.Lookup(name: str, subscripts: Tuple[list, list], expression: str)[源代码]

收件箱组件,由Vensim中的“名称(expr)”定义。此类继承自Components类。

参数:
  • name (str) -- 组件的原始名称。

  • subscripts (tuple) -- 长度为2的二元组,变量定义中的脚注列表作为第一个参数,出现在:EXCEPT:关键字(如果使用)后面的脚注列表作为第二个参数。

  • expression (str) -- 要分析的元素、表达的RHS。

parse() None[源代码]

使用parsing_grammars/lookups.peg中给出的语法和LookupsVisitor类来访问表达式的RHS,使用parsimonious解析组件对象。

get_abstract_component() AbstractLookup[源代码]

获取用于构建的抽象组件。此方法由Sections的get_abstract_section方法自动调用。

返回:

AbstractComponent --抽象组件对象,可用于以另一种语言构建模型。

返回类型:

AbstractLookup

class pysd.translators.vensim.vensim_element.Data(name: str, subscripts: Tuple[list, list], keyword: str, expression: str)[源代码]

数据组件,由Vensim中的“名称:= expr”定义。此类继承自Components类。

参数:
  • name (str) -- 组件的原始名称。

  • subscripts (tuple) -- 长度为2的二元组,变量定义中的脚注列表作为第一个参数,出现在:EXCEPT:关键字(如果使用)后面的脚注列表作为第二个参数。

  • keyword (str) -- “:=”符号之前使用的关键字。以下值是可能的:“interpolate”、“raw”、“hold_backward”和“look_forward”。

  • expression (str) -- 要分析的元素、表达的RHS。

parse() None[源代码]

使用“sparning_grammars/components. pe”中给出的语法和EquationVisitor类来节俭地解析组件对象,以访问表达的RHS。

如果表达为无,则将从Vensim中的VDF文件中读取数据。

get_abstract_component() AbstractData[源代码]

获取用于构建的抽象组件。此方法由Sections的get_abstract_section方法自动调用。

返回:

AbstractComponent --抽象组件对象,可用于以另一种语言构建模型。

返回类型:

AbstractData

支持的功能和特征

转换器的持续开发将支持Vensim功能的完整子集。当前版本支持以下操作员、功能和功能。

运营商

支持所有基本操作符,包括下表中显示的操作符。

支持的一元运算符

Vensim

文西姆例子

抽象语法

-

-A

逻辑结构( ['negative'] ,(A,))

+

+A

A

:不:

:不:A

逻辑结构( [':NOT:'] ,(A,))

支持的二进制运算符

Vensim

文西姆例子

抽象语法

^

A ^ B

算术结构( ['^'] ,(A,B))

*

A * B

算术结构( ['*'] ,(A,B))

/

A / B

算术结构( ['/'] ,(A,B))

+

A + B

算术结构( ['+'] ,(A,B))

-

A - B

算术结构( ['-'] ,(A,B))

=

A = B

逻辑结构( ['='] ,(A,B))

<>

A <> B

逻辑结构( ['<>'] ,(A,B))

<

A < B

逻辑结构( ['<'] ,(A,B))

>

A > B

逻辑结构( ['>'] ,(A,B))

>=

A >= B

逻辑结构( ['>='] ,(A,B))

<=

A <= B

逻辑结构( ['<='] ,(A,B))

:和:

A:和:B

逻辑结构( [':AND:'] ,(A,B))

或:

A:或:B

逻辑结构( [':OR:'] ,(A,B))

此外,Vensim :EXCEPT: operator is also supported to manage exceptions in the subscripts. See the 下标 科.

功能

当前支持的Vensim功能列表详细信息如下:

支持的基本功能

Vensim

文西姆例子

抽象语法

Vensim评论

ABS

ABS(A)

CallStructure('abs', (A,))

MIN

Min(A,B)

呼叫结构(' min ',(A,B))

MAX

MAX(A,B)

呼叫结构(' max ',(A,B))

SQRT

SQRT(A)

呼叫结构(' SQRT ',(A,))

EXP

EXP(A)

CallStructure('exp',(A,))

LN

LN(A)

呼叫结构(' In ',(A,))

SIN

SIN(A)

呼叫结构(' sin ',(A,))

COS

COS(A)

呼叫结构(' cos ',(A,))

TAN

TAN(A)

CallStructure('tan',(A,))

ARCSIN

阿尔克辛(A)

呼叫结构(' arcsin ',(A,))

ARCCOS

Arcos(A)

CallStructure('arccos',(A,))

ARCTAN

阿克坦(A)

呼叫结构(“arctan”,(A,))

倒置矩阵

倒置矩阵(A)

呼叫结构(' invert_matrix ',(A,))

ELMCOUNT

埃尔默斯顿(A)

CallStructure('elmcount',(A,))

INTEGER

整体(A)

CallArchitecture(' int ',(A,))

QUANTUM

量子(A,B)

呼叫结构(“量子”,(A,B))

MODULO

莫杜洛(A,B)

呼叫结构(“模”,(A,B))

IF THEN ELSE

如果有其他情况(A、B、C)

呼叫结构(' if_then_else ',(A,B))

XIDZ

XIDZ(A,B,X)

呼叫结构(' xidz ',(A,B,X))

ZIDZ

ZIDZ(A,B)

呼叫结构(' zidz ',(A,B))

VMIN

VMIN(A[dim!])

呼叫结构(' vmin ',(A,))

VMAX

MAX(A [dim!] )

CallStructure('vmax',(A,))

SUM

总和(A [dim!] )

呼叫结构(' sum ',(A,))

PROD

PROD(A [dim!] )

呼叫结构(' prod ',(A,))

PULSE

脉冲(开始、宽度)

呼叫结构('脉冲',(开始,宽度))

脉冲串

PULSE TRAIN(start, width, tbetween, end)

CallStructure('pulse_train',(start,tbetween,width,end))

RAMP

RAMP(slope、start_time、end_time)

呼叫结构(' ramp ',(slope,start_time,end_time))

STEP

Step(高度,Step_time)

CallStructure('step',(height,step_time))

获得时间价值

获取时间值(相对于、抵消、测量)

CallStructure('get_time_value',(relativeto,offset,measure))

并非所有案件都得到实施!

矢量选择

VECTOR SELECT(sel_数组 [dim!] ,BEP_数组 [dim!] 、miss_val、n_action、e_action)

CallArchitecture(' vector_select ',(sel_数组,BEP_数组,miss_val,n_action,e_action))

载体等级

VECTOR RANK(vec, direction)

呼叫结构(' vector_rank ',(vec,Direction))

向量重排序

VECTOR REOrder(vec,svec)

呼叫结构(' vector_reorder ',(vec,svec))

载体排序

VECTOR SORT ORDER(vec, direction)

呼叫结构(' vector_sort_order ',(vec,Direction))

GAME

游戏(A)

游戏结构(A)

分配可用

分配可用(请求,pp,可用)

AllocateDeliverable Architecture(请求、pp、avenue)

按优先级分配

按优先级分配(请求、优先级、尺寸、宽度、供应)

AllocateByPriorityArchitecture(请求、优先级、大小、宽度、供应)

INITIAL

初始值

初始结构(值)

如果正确,请抽样

SAMPLE IF TRUE(条件,输入,初始值)

SampleIfTrueArchitecture(条件、输入、初始值)

随机0 1

随机0 1()

呼叫结构(' random_0_1 ',())

随机均匀

随机分布(m,x,s)

CallArchitecture(' random_uniform ',(m,x,s))

随机正态

随机正态(m,x,h,r,s)

呼叫结构(' random_normal ',(m,x,h,r,s))

随机指数

随机指数(m,x,h,r,s)

呼叫结构(' random_exponential ',(m,x,h,r,s))

支持的延迟功能

Vensim

文西姆例子

抽象语法

延迟1 I

DELAY 1 I(输入、延迟时间、初始值)

延迟结构(输入,延迟_时间,初始值,1)

DELAY1

延迟1(输入,延迟时间)

延迟结构(输入,delay_time,输入,1)

延迟3 I

DELAY 3I(输入、延迟时间、初始值)

延迟结构(输入,延迟_时间,初始值,3)

延迟3

DELAY3(input,delay_time)

延迟结构(输入,delay_time,输入,3)

延迟N

延迟N(输入,延迟时间,初始值,n)

DelayNStructure(输入,delay_time,initial_Value,n)

延迟固定

DELAY FIXED(input,delay_time,initial_value)

DelayFixed(输入、delay_time、initial_Value)

SMOOTHI

SMOOTH 1I(输入、延迟时间、初始值)

SmoothFrame(输入,smth_time,initial_value,1)

SMOOTH

SMOOTH 1(输入,延迟时间)

SmothArchitecture(输入,smth_time,输入,1)

SMOOTH 3I

SMOOTH3I(input, delay_time, initial_value)

SmoothFrame(输入,smth_time,initial_value,3)

SMOOTH 3

SMOOTH 3(输入,延迟时间)

SmoothStructure(input,smth_time,input,3)

光滑N

SMOOTH N(输入,延迟时间,初始值,n)

SmothNStructure(输入,smth_time,initional_Value,n)

FORECAST

预测(输入、平均时间、地平线)

预测结构(输入,平均_时间,地平线,0)

TREND

趋势(输入、平均时间、初始趋势)

TrendStructure(input, average_time, initial_trend)

支持的get函数

Vensim

文西姆例子

抽象语法

获取XLS数据

获取XLS数据('文件',',' time_row_or_col ',',' cell ')

GetDataStructure('file','tab','time_row_or_col','cell')

获取直接数据

GET DIRECT DATA('file','tab','time_row_or_col','cell')

GetDataStructure('file','tab','time_row_or_col','cell')

获取XLS查找

获取XLS LOOKUPS('文件',' tab ',' x_row_or_col ',' cell ')'&#3

GetLookupsArchitecture('文件',' x_row_or_col ',',cell ')

直接查看

获取直接查找('文件',' tab ',' x_row_or_col ','获取直接查找(')',&#3

GetLookupsArchitecture('文件',' x_row_or_col ',',cell ')

获取XLS常数

获取XLS Constants(' file ',' tab ',' cell ')

GetConstantsStructure('file','tab','cell')

获得直接稳定性

获取直接常数(“文件”、“tab”、“cell”)

GetConstantsStructure('file','tab','cell')

获得XLS提交

GET XLS SUBSCRIPT('file','tab','first_cell','last_cell','prefix')

获得直接主题

获取直接主题('文件',' tab ',',',')

股票

股票在Vensim中定义为 INTEG(flow, initial_value) 受支持并转换为AST为 IntegStructure(flow, initial_value) .

下标

还支持几个与下标相关的特性。其中包括:

  • 不同范围的基本脚注操作。

  • 下标范围和子范围定义。

  • 基本脚注映射,其中脚注范围映射到完整范围(例如new_dim:A,B,C -> dim,dim_other)。目前尚不支持映射到部分范围(例如new_dim:A,B,C -> dim:E,F,G)。

  • 下标复制(例如new_dim <->dim)。

  • :EXCEPT:具有任意数量参数的运算符。

  • 用作变量的脚本(例如my_var [dim] =另一个var * dim)。

  • subscribe vector操作(例如SUM(my var [dim, dim!] )).

查找

支持Vensim Lookup表情。它们可以使用硬编码值、使用 GET LOOKUPS 功能或使用 WITH LOOKUPS 功能

数据

支持具有GET函数的数据定义和空数据定义(没有公式,Vensim使用VDF文件)。这些定义可能包括也可能不包括任何可能的插值关键字: :INTERPOLATE:, :LOOK FORWARD:, :HOLD BACKWARD:, :RAW:. These keywords will be stored in the 'keyword' argument of AbstractData 分别为“interpolate”、“look_forward”、“hold_backward”和“raw”。GET XLS/GROUP的抽象结构在支持的GET函数表中给出。空数据声明的抽象结构是 DataStructure .

目前,支持应用于数据的任何特定功能(例如,SEARCH IF True、TIME SEARCH.),但未来可能会包括新的。

宏观

支持Vensim宏。关键字:MACRO:和:END OF MACRO:之间的宏内容被分类为模型的一部分,随后用于从模型的其余部分构建独立的部分。

计划的新功能和功能

废弃的功能和特性

如果正确,请注意

的复杂性 SHIFT IF TRUE 函数并且需要变异另一个变量中已经计算的值,因此该函数的实现暂时已被放弃。

然而,可以使用IF THEN ELSE在库存流中重现相同的行为。中给出了一个模型,该模型具有避免“如果真”并使模型与PySD一起工作的解决方法 issue #265 .