【问题标题】:Question on Definition and values of symbols关于符号的定义和价值的问题
【发布时间】:2011-05-07 05:17:37
【问题描述】:

Definition“知道”符号值的定义方式:使用SetSetDelayed。但是怎么做?据我了解,在分配符号值后,评估器的分配方式没有任何区别:使用SetSetDelayed。它可以通过函数OwnValues 来说明,它总是返回带有Head RuleDelayed 的定义。 Definiton 是如何获取这些信息的?

In[1]:= a=5;b:=5;
Definition[a]
Definition[b]
OwnValues[a]

Out[2]= a=5
Out[3]= b:=5
Out[4]= {HoldPattern[a]:>5}

【问题讨论】:

  • Alexey 的另一个好问题。
  • 有一个非常重要的用例,它对分配中使用的内容产生了真正的影响 - SetSetDelayedPart 分配。面对tst = {1, 2, 3}; tst[[2]] = 5; tst(正常工作)和tst1 := {1, 2, 3}; tst1[[2]] = 5(给出赋值错误,tst1 没有立即值)。当然,正如您观察到的那样,tsttst1OwnValues 看起来相同。鉴于您对内存消耗的观察,我猜延迟定义可能会使用一些中间内部变量,而直接定义则直接指向存储数据的内存。

标签: wolfram-mathematica


【解决方案1】:

OwnValues[a] = {HoldPattern[a] -> 3}; OwnValues[a] 给出了{HoldPattern[a] :> 3} 而不是{HoldPattern[a] -> 3}Definition[a] 显示了可以期待的内容。可能此定义以Rule 的形式在内部存储,但被OwnValues 转换为RuleDelayed,以抑制对定义的右上方的评估。这个假设与我最初的理解相矛盾,即SetSetDelayed 分配的值之间没有区别。可能这些定义以不同的形式存储:RuleRuleDelayed 对应,但从评估者的角度来看是等效的。

看看MemoryInUse[] 是如何依赖于定义的类型很有趣。

在下面的实验中,我在没有前端的交互会话中使用了 Mathematica 5.2 的内核。 Mathematica 6 和 7 的内核会得到不同的结果。原因之一是in these versions Set is overloaded by default

首先,我评估 $HistoryLength=0; 是否具有 DownValuesInOut 变量不会影响我的结果。但似乎即使$HistoryLength 设置为 0,current 输入行的In[$Line] 的值仍会在输入新输入后存储和删除。这可能是MemoryInUse[] 的第一次评估结果总是与第二次不同的原因。

这是我得到的:

面向学生的 Mathematica 5.2:Microsoft Windows 版本

版权所有 1988-2005 Wolfram Research, Inc.

-- 终端图形初始化--

在[1]:= $HistoryLength=0;

In[2]:= MemoryInUse[]

输出[2]= 1986704

In[3]:= MemoryInUse[]

输出[3]= 1986760

In[4]:= MemoryInUse[]

输出[4]= 1986760

在[5]:= a=2;

In[6]:= MemoryInUse[]

输出[6]= 1986848

In[7]:= MemoryInUse[]

输出[7]= 1986824

In[8]:= MemoryInUse[]

输出[8]= 1986824

在[9]:= a:=2;

In[10]:= MemoryInUse[]

输出[10]= 1986976

In[11]:= MemoryInUse[]

输出[11]= 1986952

In[12]:= MemoryInUse[]

输出[12]= 1986952

在[13]:= a=2;

In[14]:= MemoryInUse[]

输出[14]= 1986848

In[15]:= MemoryInUse[]

输出[15]= 1986824

In[16]:= MemoryInUse[]

输出[16]= 1986824

可以看到定义a=2; 增加了MemoryInUse[] 1986824-1986760=64 字节。用定义 a:=2; 替换它会使 MemoryInUse[] 增加 1986952-1986824=128 字节。并用前者替换后者定义将MemoryInUse[] 恢复为1986824 字节。这意味着延迟定义比立即定义需要多 128 个字节。

当然,这个实验并不能证明我的假设。

【讨论】:

  • +1 支持您继续探索 Mathematica 的内部工作原理
【解决方案2】:

可以通过未记录的 new-in-8 符号 Language`ExtendedDefinitionLanguage`ExtendedFullDefinition 访问符号的完整定义。引用Oleksandr Rasputinov

"如果有人好奇,Language`ExtendedDefinitionLanguage`ExtendedFullDefinition 类似于 DefinitionFullDefinition,但捕获符号定义的方式可以在另一个内核中重现。例如,@ 987654328@ 返回一个Language`DefinitionList 对象。用于恢复定义的语法非常不规则:Language`ExtendedFullDefinition[] = defs,其中defsLanguage`DefinitionList。注意Language`ExtendedFullDefinition 采用ExcludedContexts 选项,而Language`ExtendedDefinition 采用不是。”

【讨论】:

    【解决方案3】:

    Information 调用Definition,而Definition(或FullDefinition)上的跟踪显示什么都没有。我必须假设这是一个访问*Values 表之外的数据的低级函数。也许它保留了当时解析的原始定义表达式的副本。

    【讨论】:

    • 解析时不是:a = 1 + 1; Definition[a] 给出a=2。我想在OwnValues 中保留有关定义的信息但不显示它:如果我们评估OwnValues[a] = {HoldPattern[a] -> 3}; Definition[a],我们会得到a = 3
    • @Alexey 在第一点上,我的意思不是“解析”,而是“评估”(我的错误)。第二,良好的观察,它与我的假设相矛盾。也可以试试:OwnValues[a] = {HoldPattern[a] :> 3}; Definition[a]我需要考虑一下。
    • @Sjoerd @Mr.你看到这个了吗? math.stackexchange.com/questions/35591/…
    • @belisarius 你是说这个具体的问题吗?我什至不知道 MO 有一个 Mathematica 标签。
    • @Sjoerd 我的目的是提醒你们两个 :)
    猜你喜欢
    • 2022-11-16
    • 1970-01-01
    • 2012-05-28
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    相关资源
    最近更新 更多