gpt4 book ai didi

wolfram-mathematica - 重载 Set[a, b] (a = b)

转载 作者:行者123 更新时间:2023-12-04 08:09:47 24 4
gpt4 key购买 nike

我想重载 Mathematica 的 Set 函数 (=),这对我来说太棘手了(参见下面的代码示例)。我成功地重载了其他函数(例如代码示例中的 Reverse)。有什么建议吗?

In[17]:= ClearAll[struct];

In[18]:= var1=struct[{1,2}]
Out[18]= struct[{1,2}]

In[19]:= Reverse@var1
Out[19]= struct[{1,2}]

In[20]:= Head[var1]
Out[20]= struct

In[21]:= struct/:Reverse[stuff_struct]:=struct[Reverse@stuff[[1]]]

In[22]:= Reverse@var1
Out[22]= struct[{2,1}]

In[23]:= struct/:Set[stuff_struct,rhs_]:=Set[struct[[1]],rhs]

In[24]:= var1="Success!"
Out[24]= Success!

In[25]:= var1
Out[25]= Success!

In[26]:= Head[var1]
Out[26]= String

In[27]:= ??struct
Global`struct
Reverse[stuff_struct]^:=struct[Reverse[stuff[[1]]]]

(stuff_struct=rhs_)^:=struct[[1]]=rhs

最佳答案

我不认为你想要的可以用 UpValues 来完成(唉),因为符号(标签)必须不超过一级定义才能工作。此外,您想要的语义在 Mathematica 中有些不寻常,因为大多数 Mathematica 表达式是不可变的(不是 L 值),并且它们的部分不能被赋值。我相信这段代码会做一些类似于你想要的事情:

Unprotect[Set];
Set[var_Symbol, rhs_] /;
MatchQ[Hold[var] /. OwnValues[var], Hold[_struct]] := Set[var[[1]], rhs];
Protect[Set];

例如:

In[33]:= var1 = struct[{1, 2}]

Out[33]= struct[{1, 2}]

In[34]:= var1 = "Success!"

Out[34]= "Success!"

In[35]:= var1

Out[35]= struct["Success!"]

但一般来说,不建议将 DownValues 添加到像 Set 这样的重要命令中,因为这可能会以微妙的方式破坏系统。

编辑

稍微解释一下您的尝试失败的原因:Mathematica 使用参数保持机制实现流控制和赋值运算符(Hold* - 属性,描述为 here)。特别是,这种机制允许它模仿分配所需的按引用传递语义。但是,在您分配给 var1 的那一刻,Set 已经不知道 var1 中存储了什么,因为它只有符号var1,而不是它的值。模式 _struct 不匹配,因为即使变量已经存储了一些 structSet 也只有变量名。为了匹配成功,Set 中的变量必须计算出它的值。但是,该值是不可变的,您不能分配给它。我建议的代码测试变量是否具有 struct[something] 形式的赋值,如果是,则修改第一部分(Part 命令是异常(exception),它可以修改 L 值表达式的某些部分,前提是这些部分已经存在)。

您可以阅读更多关于 Hold* 的主题 - 许多地方的属性和相关问题,例如 herehere

关于wolfram-mathematica - 重载 Set[a, b] (a = b),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5886066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com