DumpSave
以一种针对 Mathematica 输入进行优化的二进制格式编写定义。" 是否有一种方法可以将 Mathematica 二进制转储文件转换回定义列表而不评估它们?Import["file.mx","HeldExpression"]
不起作用...DumpSave
以一种针对 Mathematica 输入进行优化的二进制格式编写定义。" 是否有一种方法可以将 Mathematica 二进制转储文件转换回定义列表而不评估它们?Import["file.mx","HeldExpression"]
不起作用...DumpSave
函数用于存储与符号相关的值,例如OwnValues
、DownValues
、UpValues
、SubValues
、DefaultValues
、NValues
、FormatValues
。
这些值是在Mathematica会话中评估后保存的。
这些值存储在内部格式中。通过读取这个内部格式,MX文件只创建符号并将这些值填充到它们中,而绕过了求值器。
也许你可以分享一下引起你提出这个问题的问题。
f[x_Real] := x^2 + 1
DumpSave[FileNameJoin[{$HomeDirectory, "Desktop", "set_delayed.mx"}],
f];
Remove[f]
f[x_Real] = x^2 + 1;
DumpSave[FileNameJoin[{$HomeDirectory, "Desktop", "set.mx"}], f];
setBytes =
Import[FileNameJoin[{$HomeDirectory, "Desktop", "set.mx"}], "Byte"];
setDelayedBytes =
Import[FileNameJoin[{$HomeDirectory, "Desktop", "set_delayed.mx"}],
"Byte"];
可以使用SequenceAlignment[setBytes, setDelayedBytes]
来查看差异。我不知道为什么要这样做,但我的观点依然成立。在使用DumpSave
保存值之前,所有使用Set
构建的值的计算都已在Mathematica会话中完成。当读取MX文件时,内部表示将重新读入Mathematica会话,并且实际上不执行加载定义的任何计算。
Clear[f];f[x_Real]=x^2+1;DumpSave["f.mx",f];Clear[f];f=a;<<f.mx;Definition[f]
和 Clear[f]; f = a; f[x_Real] = x^2 + 1; Definition[f]
。 - Alexey PopkovDumpSave
存储与符号相关联的值,即OwnValues
、DownValues
、UpValues
、SubValues
、DefaultValues
、NValues
、FormatValues
。这些值被存储为延迟规则”显然是错误的。 - Alexey PopkovDumpSave
和 DumpGet
似乎是保存并恢复符号的原始定义的唯一方法,并且拥有保证。即使使用 Save
也不能提供这样的功能,因为它将定义存储在 Set
和 SetDelayed
定义的标准形式中,在读入导出文件时再次评估。这样,这些定义可能会被涉及符号的现有定义更改。例如,设置 x=1
将破坏对 f=x
的进一步恢复定义等。 - Alexey PopkovSave
会保存文本文件,并且Mathematica必须解析和评估这些规则以将它们转换为内部格式,而DumpSave
则保存内部结构,可以通过绕过求值器来读取。因此,将x
设置为任何值都不会影响读取回来的内容。在评估了x = 1.0; Get[ FileNameJoin[{$HomeDirectory, "Desktop", "set.mx"}]]; f[3.0]
之后,我得到了正确的值为10.0
。因此,我仍然没有看到任何问题。您能发布展示所述问题的代码吗? - Sasha.mx
文件,也没有任何可读的替代格式,但我们显然可以有它!如果“保存”将其定义以对..Values
的赋值形式保存,那么这几乎就是所需的。但是更好的方法是以某种方式能够读取.mx
文件。 - Alexey Popkov您可以将Rule
分配给DownValues,而不是RuleDelayed
,这相当于立即定义。赋值语句的右侧保持未求值状态并且被逐字复制,因此与之对应的命令也是如此。
Clear[f];
f[x_Real] = x^2 + 1;
DumpSave["f.mx", f];
Clear[f];
f = a;
<< f.mx;
Definition[f]
would be
Clear[f];
f = a;
DownValues[f] := {f[x_Real] -> x^2 + 1}
Definition[f]
f = a
f[x_Real] = x^2+1
(与您的示例Clear[f]; f = a; f[x_Real] = x^2 + 1; Definition[f]
相比,该示例可以正常工作,而不是给a[x_Real]
赋值规则)。这也适用于先前对x
的任何赋值。
编辑:它不能很好地处理右侧的副作用,如下面评论中的示例所示。要分配一个downvalue避免任何评估,可以使用未记录的System`Private`ValueList
,如下所示:
Clear[f];
f := Print["f is evaluated!"];
DownValues[f] := System`Private`ValueList[f[x_Real] -> Print["definition is evaluated!"]];
DownValues[f]
{HoldPattern[f[x_Real]] :> x^2 + 1}
但是Definition
(和Save
)显示与:=
的区别在内部已经被保留。我不知道为什么DownValues
不显示真相。
回答原始问题,您可能最好使用导入转储文件并使用Save
导出相关符号,然后,如果希望将其加载到先前定义过的内核中,可以像上面那样以编程方式将分配转换为DownValues
的分配。在导出之前,将变量范围限定在私有上下文中可能更容易,这就是系统文件所做的事情,以防止冲突。
DownValues
进行 SetDelayed
赋值时,右侧仍然会被计算,请尝试以下代码:Clear[f];f:=Print["f is evaluated!"];DownValues[f] := {f[x_Real] -> Print["definition is evaluated!"]};
(它会输出 "f is evaluated!" 和 "definition is evaluated!")。 - Alexey PopkovPrivate
ValueList”给“DownValues”的示例,http://mathematica.stackexchange.com/a/108974/6041。 因此,考虑到这一点,我认为这是一个解决方案:Clear[f]; f:= Print ["f is evaluated!"]; DownValues [f]:= System`Private`ValueList [ f [x_Real] -> Print["definition is evaluated!"]];
- The VeeLanguage`ExtendedDefinition
和 Language`DefinitionList
以相同的方式。 - Alexey Popkov
"file.mx"
可以创建自己的上下文并在任何现有上下文中添加其他定义。更糟糕的是,它可以添加或部分更改现有符号的定义。因此,仅通过比较系统两个状态来恢复其定义可能非常困难。 - Alexey PopkovFileNameJoin[{$InstallationDirectory,"SystemFiles","Kernel","SystemResources"}]
目录的适当子目录中查找。我没有安装Python,也没有相关经验,所以现在无法自行检查。但也许这个脚本是一个合适的解决方案。 - Alexey Popkov